Object ใน JavaScript การตั้งค่าและเรียกใช้ค่า property

ให้ใช้จุด(.)หรือวงเล็บเหลี่ยม([])ในการเข้าถึง หลังเครื่องหมายจุดจะเป็นชื่อ property ส่วนในวงเล็บจะต้องเป็น expression ที่ให้ผลเป็น String หรือผลที่สามารถถูกแปลงเป็น String ได้

let author = book.author;       // Get the "author" property of the book.
let name = author.surname;      // Get the "surname" property of the author.
let title = book["main title"]; // Get the "main title" property of the book.

book.edition = 7;                   // Create an "edition" property of book.
book["main title"] = "ECMAScript";  // Change the "main title" property.


ข้อดีของการใช้วงเล็บคือชื่อของ property สามารถถูกกำหนดขณะรันโปรแกรมได้


function computeValue(portfolio) {
    let total = 0.0;
    for(let stock in portfolio) {       // For each stock in the portfolio:
        let shares = portfolio[stock];  // get the number of shares
        let price = getQuote(stock);    // look up share price
        total += shares * price;        // add stock value to total value
    }
    return total;                       // Return total value.
}



การสืบทอด

เมื่อมีการอ่านค่า property x จาก object ใดๆ JavaScript จะหาค่าของ property จาก object นั้นๆก่อน
ถ้าไม่เจอก็จะสืบค้นขึ้นไปเรื่อยตาม prototype chain จนสุดที่ object ที่ไม่มี prototype จึงจะคือค่า undefined

ต่างจากการให้ค่า property ที่ถ้า object ไม่มี property x , x จะถูกสร้างขึ้นมาก่อนที่ object นั้นแล้วจึงให้ค่า
หากใน prototype มี property ชื่อเดียวกัน property นั้นก็จะถูกบังไว้เพราะจะอ่านไปไม่ถึง ถ้า property มี getter/setter ตัว setter ก็จะถูกเรียกใช้บน object นั้นๆแทน


let unitcircle = { r: 1 };         // An object to inherit from
let c = Object.create(unitcircle); // c inherits the property r
c.x = 1; c.y = 1;                  // c defines two properties of its own
c.r = 2;                           // c overrides its inherited property
unitcircle.r                       // => 1: the prototype is not affected


Errors เมื่อเรียกค่า property

การเรียกค่า property จาก null หรือ undefined จะทำให้เกิดข้อผิดพลาด TypeError แสดงขึ้นมา
สามารถป้องกันได้ด้วย


// A verbose and explicit technique
let surname = undefined;
if (book) {
    if (book.author) {
        surname = book.author.surname;
    }
}

หรือ
let surname = book?.author?.surname;


การให้ค่ากับ property  p ของ Object o จะเกิด error ขึ้นในกรณี
  • o มี property p อยู่แต่เป็นแบบอ่านได้เท่านั้น
  • o สืบทอด property p มา แต่ p อ่านได้เท่านั้น
  • o ไม่มี p ใน prototype chain ก็ไม่มี p และ extensible attrbute ของ o เป็น false

การลบ Property

ใช้ delete operator

delete book.author;          // The book object now has no author property.
delete book["main title"];   // Now it doesn't have "main title", either.

delete operator จะลบ property ที่เป็นของ object นั้นเท่านั้น จะไม่ลบ property ที่มาจาก prototype

let x={a:1,b:2}; //prototype object
let y=Object.create(x); Object y, x as prototype
let z=Object.create(x); Object z, x as prototype
y.c=3; //create new property
y.a=4;
delete y.a; //delete property a from y
delete y.c; //delete property c from y
delete y.a; // attempt to delete a again, nothing happen
delete x.a; //delete a from x, prototype object. Both y and z are affected.

delete operator ส่วนใหญ่จะคืนค่าเป็น true

let o = {x: 1};    // o has own property x and inherits property toString
delete o.x         // => true: deletes property x
delete o.x         // => true: does nothing (x doesn't exist) but true anyway
delete o.toString  // => true: does nothing (toString isn't an own property)
delete 1           // => true: nonsense, but true anyway

ใน strick mode การลบ property ที่ configurable เป็น false จะทำให้เกิด  TypeError

// In strict mode, all these deletions throw TypeError instead of returning false
delete Object.prototype // => false: property is non-configurable
var x = 1;              // Declare a global variable
delete globalThis.x     // => false: can't delete this property


การทดสอบ property

  • in operator
let o = { x: 1 };
"x" in o         // => true: o has an own property "x"
"y" in o         // => false: o doesn't have a property "y"
"toString" in o  // => true: o inherits a toString property
  • hasOwnproperty() method
let o = { x: 1 };
o.hasOwnProperty("x")        // => true: o has an own property x
o.hasOwnProperty("y")        // => false: o doesn't have a property y
o.hasOwnProperty("toString") // => false: toString is an inherited property
  • propertyIsEnumerable() method.
ทดสอบทั้ง Enumerable กับ own property .
let o = { x: 1 };
o.propertyIsEnumerable("x")  // => true: o has an own enumerable property x
  • ใช้ !==  
ทดสอบว่ามี property หรือ มีแต่มีค่าเป็น undefined
let o = { x: 1 };
o.x !== undefined        // => true: o has a property x
o.y !== undefined        // => false: o doesn't have a property y or it has 'undefined as value'
o.toString !== undefined // => true: o inherits a toString property



Comments

Popular posts from this blog

15.8.4 การวาดลงบน cavas

15.8.3 Graphics Attributes

Class ใน JavaScript, การสร้าง class ด้วย keyword class