ข้อบ่งชี้พร็อพเพอร์ตี้

การโต้ตอบส่วนใหญ่ระหว่างคุณกับพร็อพเพอร์ตี้ออบเจ็กต์มักจะ ระดับพื้นผิว รวมถึงการสร้างลิเทอรัลวัตถุและการตั้งค่าและการเข้าถึง ค่าพร็อพเพอร์ตี้โดยใช้คีย์ แต่คุณสามารถกำหนดค่าพร็อพเพอร์ตี้ใดๆ สำหรับการควบคุมโดยละเอียดเกี่ยวกับวิธีเข้าถึงพร็อพเพอร์ตี้เหล่านั้น เปลี่ยนแปลงและนิยาม พร็อพเพอร์ตี้ออบเจ็กต์ทุกรายการมีชุดแอตทริบิวต์ที่มองไม่เห็น ซึ่งมีข้อมูลเมตาที่เชื่อมโยงกับพร็อพเพอร์ตี้นั้น ซึ่งเรียกว่า "พร็อพเพอร์ตี้ ข้อบ่งชี้"

พร็อพเพอร์ตี้ใดๆ ก็ตามมีข้อบ่งชี้ 2 ประเภทดังนี้ ข้อบ่งชี้ข้อมูลและข้อบ่งชี้เครื่องมือเข้าถึง โดยข้อบ่งชี้ข้อมูลประกอบด้วย คู่คีย์และค่าที่มีค่าของพร็อพเพอร์ตี้ โดยไม่คำนึงว่า สามารถเขียนได้ กำหนดค่า หรือแจกแจงได้ ตัวบ่งชี้ตัวเข้าถึงประกอบด้วย ที่ดำเนินการเมื่อมีการตั้งค่า เปลี่ยนแปลง หรือเข้าถึงพร็อพเพอร์ตี้

พร็อพเพอร์ตี้ ประเภทข้อบ่งชี้ ค่าเริ่มต้นจาก
Object.defineProperty()
คำอธิบาย
[[Value]] ข้อมูล undefined มีค่าของพร็อพเพอร์ตี้
[[Writable]] ข้อมูล false กำหนดว่าคุณสามารถเปลี่ยนค่าของพร็อพเพอร์ตี้ได้หรือไม่
[[Get]] ผู้เข้าถึง undefined ฟังก์ชัน getter ของพร็อพเพอร์ตี้ ซึ่งจะทำงานเมื่อฟังก์ชัน มีการเข้าถึงพร็อพเพอร์ตี้
[[Set]] ผู้เข้าถึง undefined ฟังก์ชัน setter ของพร็อพเพอร์ตี้ ซึ่งจะทำงานเมื่อฟังก์ชัน มีการตั้งค่าหรือเปลี่ยนแปลงพร็อพเพอร์ตี้
[[Configurable]] ทั้งคู่ false หากนี่คือ false คุณจะลบพร็อพเพอร์ตี้และ ไม่สามารถเปลี่ยนแอตทริบิวต์ได้ หากนี่คือ false และ [[Writable]] เท่ากับ true ค่าของพร็อพเพอร์ตี้สามารถ จะยังคงมีการเปลี่ยนแปลง
[[Enumerable]] ทั้งคู่ false หากเป็น true คุณสามารถทำซ้ำพร็อพเพอร์ตี้โดยใช้ for...in ลูป หรือ Object.keys() คงที่

พร็อพเพอร์ตี้แต่ละรายการเหล่านี้ใช้ชวเลขเดียวกับ [[Prototype]] เพื่อบ่งบอกว่า พร็อพเพอร์ตี้เหล่านี้ไม่ได้มีไว้เพื่อเข้าถึงโดยตรง ให้ใช้ Object.defineProperty() เมธอดแบบคงที่เพื่อกำหนดหรือแก้ไขคุณสมบัติของพร็อพเพอร์ตี้ ออบเจ็กต์ Object.defineProperty() ยอมรับอาร์กิวเมนต์ 3 ตัว ได้แก่ ออบเจ็กต์ที่จะดำเนินการ คีย์พร็อพเพอร์ตี้ที่จะสร้างหรือแก้ไข และออบเจ็กต์ที่มี ข้อบ่งชี้ที่เชื่อมโยงกับพร็อพเพอร์ตี้ที่กำลังสร้างหรือแก้ไข

โดยค่าเริ่มต้น พร็อพเพอร์ตี้ที่สร้างขึ้นโดยใช้ Object.defineProperty() ไม่สามารถเขียน แจกแจง หรือกำหนดค่าได้ แต่พร็อพเพอร์ตี้ที่คุณสร้าง เป็นส่วนหนึ่งของอ็อบเจ็กต์ลิเทอรัล หรือใช้สัญลักษณ์จุดหรือวงเล็บเป็น สามารถเขียนได้ สามารถแจกแจงได้ และกำหนดค่าได้

const myObj = {};

Object.defineProperty(myObj, 'myProperty', {
  value: true,
  writable: false
});

myObj.myProperty;
> true

myObj.myProperty = false;

myObj.myProperty;
> true

ตัวอย่างเช่น เมื่อ [[Writable]] มีค่า false ให้พยายามตั้งค่าใหม่ สำหรับพร็อพเพอร์ตี้ที่เกี่ยวข้องไม่ทำงานนอกโหมดเข้มงวดโดยไม่มีการแจ้งเตือน และมีการส่ง ข้อผิดพลาดในโหมดเข้มงวด:

{
    const myObj = {};

    Object.defineProperty(myObj, 'myProperty', {
    value: true,
    writable: false
    });

    myObj.myProperty = false;
    myObj.myProperty;
}
> true

(function () {
    "use strict";
    const myObj = {};

    Object.defineProperty(myObj, 'myProperty', {
    value: true,
    writable: false
    });

    myObj.myProperty = false;
    myObj.myProperty;
}());\
> Uncaught TypeError: "myProperty" is read-only

การใช้ข้อบ่งชี้อย่างมีประสิทธิภาพเป็นแนวคิดที่ค่อนข้างขั้นสูง แต่ การทำความเข้าใจโครงสร้างภายในของวัตถุ จำเป็นต่อการทำความเข้าใจ ไวยากรณ์ที่เกี่ยวข้องกับการทำงานกับออบเจ็กต์ด้วยวิธีทั่วไป ตัวอย่างเช่น แนวคิดเหล่านี้จะนำมาใช้เมื่อใช้เมธอด Object.create() แบบคงที่ ซึ่งช่วยให้คุณสามารถควบคุมต้นแบบที่แนบกับ ออบเจ็กต์

Object.create() สร้างออบเจ็กต์ใหม่โดยใช้ออบเจ็กต์ที่มีอยู่เป็น ต้นแบบ ซึ่งจะช่วยให้วัตถุใหม่รับคุณสมบัติและเมธอดมาจากอีกรายการได้ ออบเจ็กต์ที่ผู้ใช้กำหนดในลักษณะเดียวกับที่ออบเจ็กต์สืบทอดพร็อพเพอร์ตี้ ต้นแบบ Object ในตัวของ JavaScript เมื่อคุณเรียกใช้ Object.create() ด้วย เป็นอาร์กิวเมนต์ โดยสร้างวัตถุว่างที่มีอ็อบเจ็กต์ที่ส่งผ่าน เครื่องต้นแบบ

const myCustomPrototype = {
  'myInheritedProp': 10
};

const newObject = Object.create( myCustomPrototype );

newObject;
> Object {  }
<prototype>: Object { myInheritedProp: 10 }
  myInheritedProp: 10
  <prototype>: Object { … }

Object.create สามารถใช้อาร์กิวเมนต์ที่ 2 ที่ระบุพร็อพเพอร์ตี้ของตนเองสำหรับ ออบเจ็กต์ที่สร้างขึ้นใหม่โดยใช้ไวยากรณ์ที่คล้ายกับ Object.defineProperty()— ซึ่งก็คือคีย์การแมปออบเจ็กต์กับชุดแอตทริบิวต์ข้อบ่งชี้

const myCustomPrototype = {
  'myInheritedProp': 10
};

const myObj = Object.create( myCustomPrototype, {
        myProperty: {
            value: "The new property value.",
            writable: true,
            configurable: true
        }
  });

myObj;
> Object { … }
    myProperty: "The new property value."
    <prototype>: Object { myInheritedProp: 10 }

ในตัวอย่างนี้ ออบเจ็กต์ใหม่ (myObj) ใช้ออบเจ็กต์ลิเทอรัล (myCustomPrototype) เป็นต้นแบบ ซึ่งในตัวเองจะมีโค้ดที่รับช่วงมา Object.prototype ส่งผลให้เกิดชุดต้นแบบที่รับช่วงมาซึ่งเรียกว่า เชนต้นแบบ แต่ละออบเจ็กต์มีต้นแบบ ไม่ว่าจะได้รับการมอบหมายหรือรับค่ามา ซึ่งมีต้นแบบของตัวเองหรือที่รับช่วงมา เชนนี้สิ้นสุดที่เวลา null ซึ่งไม่มีต้นแบบของตัวเอง

const myPrototype = {
  'protoProp': 10
};

const newObject = Object.setPrototypeOf( { 'objProp' : true }, myPrototype );

newObject;
> Object { objProp: true }
    objProp: true
    <prototype>: Object { protoProp: 10 }
        protoProp: 10
        <prototype>: Object { … }

พร็อพเพอร์ตี้ที่อยู่ในต้นแบบของค่าจะอยู่ใน "ระดับบนสุด" ของออบเจ็กต์ได้โดยไม่จำเป็นต้องเข้าถึงพร็อพเพอร์ตี้ต้นแบบโดยตรง

const objectLiteral = {
    "value" : true
};

objectLiteral;
> Object { value: true }
    value: true
    <prototype>: Object { … }

objectLiteral.toString();
"[object Object]"

รูปแบบนี้ยังคงใช้ได้กับห่วงโซ่ต้นแบบทั้งหมดที่เชื่อมโยงกับ : เมื่อพยายามเข้าถึงพร็อพเพอร์ตี้ ล่ามจะมองหาสิ่งนั้น พร็อพเพอร์ตี้ในแต่ละ "ระดับ" ของห่วงโซ่ต้นแบบ จากบนลงล่างจนถึง ค้นหาอสังหาริมทรัพย์หรือห่วงโซ่สิ้นสุด:

const myCustomPrototype = {
  'protoProp': "Prototype property value."
};

const myObj = Object.create( myCustomPrototype, {
    myProperty: {
        value: "Top-level property value.",
        writable: true,
        configurable: true
    }
});

myObj.protoProp;
> "Prototype property value."

ตรวจสอบความเข้าใจ

ตัวบ่งชี้ใดคือตัวเข้าถึง

[[Get]]
[[Set]]
[[Writable]]