Ang klase ng `Object` sa JavaScript
Ipinapaliwanag ng artikulong ito ang klase ng Object sa JavaScript.
Ipinapaliwanag ng artikulong ito ang klase ng Object sa JavaScript, kasama ang mga praktikal na halimbawa.
YouTube Video
Ang klase ng Object sa JavaScript
Ang Object ay isang built-in na object na nagsisilbing base ng lahat ng mga object sa JavaScript. Marami sa mga pangunahing tampok ng wika, tulad ng pamamahala ng ari-arian, mana (prototype chain), pag-enumerate, pag-clone, at pag-freeze, ay ibinibigay sa pamamagitan ng pag-uugali ng Object.
Object.create
Maraming paraan upang lumikha ng mga object, at dapat piliin ang angkop na paraan depende sa iyong layunin.
Object literal (pinakakaraniwan)
Ipinapakita ng sumusunod na code ang pinaka-simpleng at pinaka-nababasang paraan para lumikha ng object.
1// Create an object using object literal
2const user = {
3 name: "Alice",
4 age: 30,
5 greet() {
6 return `Hello, I'm ${this.name}`;
7 }
8};
9
10console.log(user.greet()); // "Hello, I'm Alice"
- Sa halimbawa na ito, ang mga property at metodo ay tinutukoy gamit ang mga literal. Ito ay simple at karaniwang nag-aalok ng mas mataas na pagganap.
new Object() constructor
Bihirang gamitin ang Object constructor, ngunit mahalagang maunawaan ang kanyang pag-uugali.
1// Create an object using the Object constructor
2const objFromCtor = new Object();
3objFromCtor.x = 10;
4objFromCtor.y = 20;
5
6console.log(objFromCtor); // { x: 10, y: 20 }
new Object()ay nagbabalik ng empty object, ngunit mas maikli at mas karaniwan ang literal na{}.
Pagtatakda ng prototype gamit ang Object.create
Ginagamit ang Object.create upang lumikha ng object na may tinukoy na prototype.
1// Create an object with a specified prototype
2const proto = { hello() { return "hi"; } };
3const obj = Object.create(proto);
4obj.name = "Bob";
5
6console.log(obj.hello()); // "hi"
7console.log(Object.getPrototypeOf(obj) === proto); // true
- Ang
Object.createay mainam para sa disenyo ng object na nakabatay sa inheritance, dahil hinahayaan kang kontrolin nang eksakto ang prototype chain.
Mga katangian at deskriptor ng property
Ang mga property ay may mga katangian tulad ng 'value', 'writable', 'enumerable', at 'configurable' na maaaring kontrolin nang detalyado gamit ang Object.defineProperty.
Pangunahing halimbawa ng paggamit ng defineProperty
Susunod ay isang halimbawa ng pagtukoy ng hindi na-enumerate at read-only na mga property gamit ang defineProperty.
1// Define a non-enumerable read-only property
2const person = { name: "Carol" };
3
4Object.defineProperty(person, "id", {
5 value: 12345,
6 writable: false,
7 enumerable: false,
8 configurable: false
9});
10
11console.log(person.id); // 12345
12console.log(Object.keys(person)); // ["name"] — "id" is non-enumerable
13person.id = 999; // silently fails or throws in strict mode
14console.log(person.id); // still 12345
- Ang paggamit ng
definePropertyay nagbibigay-daan sa iyo na eksaktong kontrolin ang kilos ng mga property gaya ng pag-enumerate, pag-rewrite, at pagtanggal.
Mga Accessor Property (getter / setter)
Sa pamamagitan ng accessors, maaari kang maglagay ng lohika sa pagbasa at pagsulat ng property.
1// Use getter and setter to manage internal state
2const data = {
3 _value: 1,
4 get value() {
5 return this._value;
6 },
7 set value(v) {
8 if (typeof v === "number" && v > 0) {
9 this._value = v;
10 } else {
11 throw new Error("value must be a positive number");
12 }
13 }
14};
15
16console.log(data.value); // 1
17data.value = 5;
18console.log(data.value); // 5
19// data.value = -1; // would throw
- Gamit ang
getteratsetter, maaari mong ituring ang property access na parang external API at magdagdag ng validation o iba pang epekto.
Prototype at inheritance (prototype / __proto__ / Object.getPrototypeOf)
Ang inheritance sa JavaScript ay nakabatay sa prototype chain, hindi sa mga klase. Maaaring sumangguni ang mga object sa ibang object bilang kanilang mga prototype.
Object.getPrototypeOf at Object.setPrototypeOf
Ipinapakita ng susunod na halimbawa kung paano i-inspeksyunin at itakda ang mga prototype.
1// Inspect and change prototype
2const base = { speak() { return "base"; } };
3const derived = Object.create(base);
4console.log(Object.getPrototypeOf(derived) === base); // true
5
6const other = { speak() { return "other"; } };
7Object.setPrototypeOf(derived, other);
8console.log(derived.speak()); // "other"
- Ang
Object.getPrototypeOfay kumukuha ng prototype ng isang object. - Binabago ng
Object.setPrototypeOfang prototype ng umiiral na object, ngunit gamitin ito nang maingat dahil maaaring maapektuhan ang performance.
Mahalagang mga built-in na pamamaraan
Ipapaliwanag namin nang malinaw ang mga pinaka-madalas gamitin at mahahalagang pamamaraan na pinili mula sa mga instance methods na ibinibigay ng Object.prototype, pati na rin ang mga static methods na pagmamay-ari ng Object.
hasOwnProperty, isPrototypeOf, toString, valueOf
Ang hasOwnProperty, isPrototypeOf, toString, at valueOf ay tumutukoy sa mga pangunahing kilos ng mga object.
1// Demonstrate prototype methods
2const base = { greet() { return "hello"; } };
3const child = Object.create(base);
4const a = { x: 1 };
5
6console.log(a.hasOwnProperty("x")); // true
7console.log(a.hasOwnProperty("toString")); // false — toString is inherited
8
9console.log(a.toString()); // "[object Object]" by default
10
11console.log(base.isPrototypeOf(child)); // true
12console.log(Object.prototype.isPrototypeOf(child)); // true
- Ang
hasOwnPropertyay mahalagang method upang suriin kung ang property ay direktang pagmamay-ari ng object. - Ang
isPrototypeOfay tinitingnan kung ang target na object ay may sarili bilang prototype.
Object.keys, Object.values, Object.entries
Object.keys, Object.values, at Object.entries ay nagbabalik ng mga listahan ng sariling enumerable properties ng object. Nakakatulong ang mga ito sa iteration at transformation.
1// Keys, values and entries
2const item = { id: 1, name: "Widget", price: 9.99 };
3
4// ["id", "name", "price"]
5console.log(Object.keys(item));
6
7// [1, "Widget", 9.99]
8console.log(Object.values(item));
9
10// [["id",1], ["name","Widget"], ["price",9.99]]
11console.log(Object.entries(item));- Madalas itong ginagamit sa pag-ikot at pagbabago ng mga object.
Object.assign
Ginagamit ang Object.assign para sa mababaw na pagkopya at pagsasama. Tandaan na ang mga prototype at accessor property ay hindi nakokopya.
1// Shallow copy / merge using Object.assign
2const target = { a: 1 };
3const source = { b: 2 };
4const result = Object.assign(target, source);
5
6console.log(result); // { a: 1, b: 2 }
7console.log(target === result); // true (merged into target)
- Para sa mga nested na object, tanging reference lang ang kinokopya kaya kailangan ng ibang paraan para sa deep cloning.
Object.freeze, Object.seal, Object.preventExtensions
Ang Object.freeze, Object.seal, at Object.preventExtensions ay kumokontrol sa mutability ng mga object.
1// Freeze vs seal vs preventExtensions
2const obj = { a: 1 };
3Object.freeze(obj);
4obj.a = 2; // fails silently or throws in strict mode
5delete obj.a; // fails
6
7const obj2 = { b: 2 };
8Object.seal(obj2);
9obj2.b = 3; // allowed
10// delete obj2.b; // fails
11
12const obj3 = { c: 3 };
13Object.preventExtensions(obj3);
14obj3.d = 4; // fails
- Ang
freezeang pinakastikto; pinipigilan nitong mabago ang anumang property ng object. - Ang
sealay pumipigil sa pagdagdag o pagtanggal ng mga property, ngunit pinapayagan ang pagbabago ng mga umiiral na halaga ng property. - Ang
preventExtensionsay humahadlang lamang sa pagdagdag ng bagong mga property; ang umiiral na mga property ay maaari pa ring baguhin o tanggalin.
Enumerability ng object, pagkakasunod-sunod, at for...in / for...of
Ang for...in ay nag-eenumerate ng mga enumerable property name, ngunit pati na rin ang mga property mula sa prototype chain, kaya madalas itong ginagamit kasama ng hasOwnProperty. Mas ligtas ang pagsasama ng Object.keys() sa for...of at mas malinaw ang iyong layunin.
1// Safe enumeration
2const obj = Object.create({ inherited: true });
3obj.own = 1;
4
5for (const key in obj) {
6 if (obj.hasOwnProperty(key)) {
7 console.log("own prop:", key);
8 } else {
9 console.log("inherited prop:", key);
10 }
11}
12
13for (const key of Object.keys(obj)) {
14 console.log("key via Object.keys:", key);
15}- Ang mga patakaran para sa enumeration ng property ay tinukoy sa ECMAScript specification, at may mga pagkakataon na garantisado ang order ng enumeration at kung minsan ay hindi naman. Bilang pangkalahatang tuntunin, ang mga key na binibigyang-kahulugan bilang mga numero ay isinaayos ayon sa pataas na pagkakasunod-sunod, habang ang ibang mga key ay sumusunod sa pagkakasunod ng pagpasok.
Pagkopya at deep copying
May dalawang uri ng pagkopya ng object: shallow copying gamit ang Object.assign o ang spread syntax, at deep copying gamit ang recursive na mga pamamaraan. Mahalaga na gamitin ang mga ito nang naaayon depende sa sitwasyon.
Mababaw na pagkopya (spread syntax / Object.assign)
1// Shallow copy with spread operator
2const original = { a: 1, nested: { x: 10 } };
3const shallow = { ...original };
4shallow.nested.x = 99;
5console.log(original.nested.x); // 99 — nested object is shared
- Sa mababaw na pagkopya, magkasalo ng reference ang mga nested object, kaya ang pagbabago sa orihinal ay makakaapekto rin sa kopya.
Simpleng deep copy (may babala)
Ang paggamit ng JSON trick ay mabilis na paraan para sa deep copy, ngunit may kahinaan tulad ng pagkawala ng mga function, Date, circular reference, at undefined values. Para sa tunay na deep cloning, dapat gumamit ng espesyal na library.
1// Deep clone using JSON methods — limited use-cases only
2const source = { a: 1, d: new Date(), nested: { x: 2 } };
3const cloned = JSON.parse(JSON.stringify(source));
4console.log(cloned); // ok for plain data, but Date becomes string, functions lost
- Ang mga pamamaraan na nakabatay sa JSON ay maginhawa para sa mabilisang paghawak ng simpleng datos, ngunit sa karaniwang mga kaso, maaaring masira ang kanilang pag-uugali.
Mixins at object composition
Sa halip na multiple inheritance, kadalasang ginagamit ang pattern ng pagtatambal ng mga gawi gamit ang mixins.
1// Simple mixin function
2const canEat = {
3 eat() { return `${this.name} eats`; }
4};
5const canWalk = {
6 walk() { return `${this.name} walks`; }
7};
8
9function createPerson(name) {
10 const person = { name };
11 return Object.assign(person, canEat, canWalk);
12}
13
14const p = createPerson("Dana");
15console.log(p.eat()); // "Dana eats"
16console.log(p.walk()); // "Dana walks"
- Ang mixins ay flexible, ngunit kailangang pag-ingatan ang pagbangga ng pangalan ng property at ang testability.
Karaniwang bitag at pinakamahusay na kasanayan
Narito ang ilang karaniwang bitag at pinakamahusay na kasanayan.
-
Mutability Ang mga object ay mutable bilang default. Sa mga application na may state management, ikonsidera ang paggamit ng immutable na mga data structure gamit ang
Object.freezeo isang immutable na library. -
Prototype Pollution Ang pag-merge ng external data sa isang object gamit ang
Object.assigno loops ay maaaring magdulot ng hindi inaasahang epekto sa mga espesyal na property gaya ng__proto__oconstructor, na nagdudulot ng panganib sa seguridad. I-filter ang input ng user bago direktang i-merge. -
Mga Bitag ng
for...inAngfor...inay nag-eenumerate din ng mga property mula sa prototype, kaya siguraduhing suriin gamit anghasOwnProperty. Mas malinaw ang paggamit ngObject.keys. -
Maling Paggamit ng Shallow Copy Isaalang-alang kung kailangan ng deep copying upang maiwasan ang pagbabago sa nested na object na makaapekto sa orihinal.
Praktikal na Halimbawa: Pattern ng Pag-update ng Immutable na Object
Ang mga pattern na nagbabalik ng bagong object nang hindi direktang binabago ang state ay karaniwang ginagamit sa React at katulad na mga library.
1// Immutable update example
2const state = { todos: [{ id: 1, text: "Buy milk", done: false }] };
3
4// Toggle todo done immutably
5function toggleTodo(state, todoId) {
6 return {
7 ...state,
8 todos: state.todos.map(t => t.id === todoId ? { ...t, done: !t.done } : t)
9 };
10}
11
12const newState = toggleTodo(state, 1);
13console.log(state.todos[0].done); // false
14console.log(newState.todos[0].done); // true
- Ang code na ito ay halimbawa ng paglikha ng bagong state object nang hindi direktang binabago ang orihinal na
stateobject. Kinokopya ng function natoggleTodoangtodosarray at nagbabalik ng bagong object kung saan tanging ang target na elemento lamang ang binago, kaya ang orihinal nastateay nananatiling hindi nagbago. - Ang immutable na pag-update ay nagpapababa ng side effects at nagpapadali sa pamamahala ng state.
Praktikal na Halimbawa: Ligtas na Pagsasama (Mag-ingat sa Prototype Pollution)
Kapag nag-merge ng external JSON, i-ignore ang __proto__ upang maiwasan ang prototype pollution.
1// Safe merge ignoring __proto__ keys
2function safeMerge(target, source) {
3 for (const key of Object.keys(source)) {
4 if (key === "__proto__" || key === "constructor") continue;
5 target[key] = source[key];
6 }
7 return target;
8}
9
10const target = {};
11const source = JSON.parse('{"a":1,"__proto__":{"polluted":true}}');
12safeMerge(target, source);
13console.log(target.polluted); // undefined — safe
14console.log({}.polluted); // undefined — prototype not polluted
- Mahalaga rin ang ganitong uri ng proteksyon sa mga library at framework.
Mga Pagsasaalang-alang sa Performance
Tungkol sa performance, isaalang-alang ang mga sumusunod:.
- Iwasan ang madalas na pagbabago ng prototype (
Object.setPrototypeOf) o dynamic na pagdagdag/pag-alis ng property, dahil nakakaapekto ito sa optimization ng engine. - Kapag gumagawa ng maraming maliliit na object, mas epektibo ang optimization kung gagamit ka ng mga object na may iisang istraktura (parehong set ng mga katangian).
- Mahal ang deep copying. Bawasan ang paggamit nito o isaalang-alang ang diff-based na pag-update.
Buod
Mahalaga ang Object sa JavaScript, nagbibigay ito ng iba't ibang feature tulad ng paglikha ng object, kontrol ng property, inheritance, pagkopya, at pamamahala ng mutability. Mahalagang maunawaan ang mga API tulad ng Object.defineProperty, Object.assign, at Object.freeze, at magdisenyo nang maingat upang maiwasan ang mga bitag tulad ng prototype pollution at shallow copying.
Maaari mong sundan ang artikulo sa itaas gamit ang Visual Studio Code sa aming YouTube channel. Paki-check din ang aming YouTube channel.