เช่นเดียวกับข้อมูลประเภทอื่นๆ
ได้รับคุณสมบัติและเมธอดมาจากต้นแบบ Object
ในตัว
ซึ่งหมายความว่าออบเจ็กต์ที่ได้จะมีทั้งพร็อพเพอร์ตี้ที่คุณกำหนดและ
พร็อพเพอร์ตี้ต้นแบบที่มีเมธอดที่รับช่วงมาจากต้นแบบ
let myObject = {
'booleanValue' : true
};
myObject;
> Object { booleanValue: true }
booleanValue: true
[[prototype]]: Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__: …
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
พร็อพเพอร์ตี้ต้นแบบไม่ได้มีไว้เพื่อเข้าถึงโดยตรงด้วยคีย์ของพร็อพเพอร์ตี้ อาส
ที่คุณอาจเห็นในตัวอย่างก่อนหน้านี้คือ [[prototype]]
หรือสัญลักษณ์ <prototype>
ที่ใช้ในเบราว์เซอร์ คอนโซลของนักพัฒนาซอฟต์แวร์และแหล่งที่มาของ
เอกสารประกอบสำหรับคีย์พร็อพเพอร์ตี้ของต้นแบบ
// Chrome:
let emptyObject = {};
emptyObject;
> {}
[[prototype]]: Object
// Firefox:
let emptyObject = {};
emptyObject;
> Object { }
<prototype>: Object { … }
แม้ว่าเบราว์เซอร์ทั่วไปทั้งหมดจะใช้ __proto__
เป็นมาตรฐานโดยปริยาย แต่นี่ไม่ใช่
กำหนดเป็นมาตรฐานอย่างเป็นทางการ และควรหลีกเลี่ยงการใช้ในโค้ดที่ใช้งานจริง
let emptyObject = {};
emptyObject.__proto__;
> Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__:
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
แต่คุณจะเข้าถึงและแก้ไข [[Prototype]]
ของออบเจ็กต์ได้โดยตรง
โดยใช้ Object.getPrototypeOf()
และ Object.setPrototypeOf()
ในตัว
วิธีการ:
let myObj = { "value" : 5 };
let protoParent = { "protoValue" : true };
myObj;
Object { value: 5 }
value: 5
<prototype>: Object { … }
Object.getPrototypeOf( myObj );
> Object { … }
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
__proto__:
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toString: function toString()
valueOf: function valueOf()
<get __proto__()>: function __proto__()
<set __proto__()>: function __proto__()
Object.setPrototypeOf( myObj, protoParent );
> Object { value: 5 }
value: 5
<prototype>: Object { protoValue: true }
หากต้องการแยกความแตกต่างระหว่างพร็อพเพอร์ตี้ที่รับช่วงและพร็อพเพอร์ตี้ที่ผู้เขียนกำหนด ซึ่งโดยทั่วไปจะเรียกว่า "คุณสมบัติของตัวเอง" ของวัตถุ
เมธอด Object.hasOwn()
ในตัวจะแสดง true
หากพร็อพเพอร์ตี้ที่ระบุ
เป็นพร็อพเพอร์ตี้โดยตรงของออบเจ็กต์ และ false
หากพร็อพเพอร์ตี้รับค่ามา หรือ
ไม่มีอยู่ ใช้ Object.hasOwn()
ทุกครั้งที่ทำได้
แทนที่จะเป็นเมธอด hasOwnProperty()
ที่รับช่วงมา ซึ่งไม่สนับสนุน
Object.create()
let myObject = {
'myValue' : 100
};
Object.hasOwn( myObject, 'myValue' );
> true
myObject.__proto__; // The Object prototype inherited by `myObject` is present:
> Object { … }
Object.hasOwn( myObject, '__proto__' ); // The Object prototype inherited by `myObject` is not an "own property:"
> false
ตรวจสอบความเข้าใจ
เหตุใดคุณจึงควรหลีกเลี่ยงการใช้ __proto__