วิธีใช้ javascript Object.defineProperty


183

ฉันมองไปรอบ ๆ เพื่อใช้Object.definePropertyวิธีการ แต่ไม่พบสิ่งที่เหมาะสม

มีคนให้ข้อมูลโค้ดนี้กับฉัน:

Object.defineProperty(player, "health", {
    get: function () {
        return 10 + ( player.level * 15 );
    }
})

แต่ฉันไม่เข้าใจ ส่วนใหญ่getเป็นสิ่งที่ฉันไม่สามารถได้รับ (ปุนตั้งใจ) มันทำงานยังไง?


1
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ......นี่คือบทแนะนำที่ยอดเยี่ยมที่นี่
Martian2049

คำตอบ:


499

เมื่อคุณถามคำถามที่คล้ายกันลองทำทีละขั้นตอน อีกหน่อย แต่มันอาจช่วยให้คุณประหยัดเวลาได้มากกว่าที่ฉันเขียนไว้:

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

function Product(name,price) {
  this.name = name;
  this.price = price;
  this.discount = 0;
}

var sneakers = new Product("Sneakers",20); // {name:"Sneakers",price:20,discount:0}
var tshirt = new Product("T-shirt",10);  // {name:"T-shirt",price:10,discount:0}

จากนั้นในรหัสลูกค้าของคุณ (e-shop) คุณสามารถเพิ่มส่วนลดให้กับผลิตภัณฑ์ของคุณ:

function badProduct(obj) { obj.discount+= 20; ... }
function generalDiscount(obj) { obj.discount+= 10; ... }
function distributorDiscount(obj) { obj.discount+= 15; ... }

ต่อมาเจ้าของ e-shop อาจตระหนักว่าส่วนลดนั้นไม่สามารถมากกว่า 80% ได้ ตอนนี้คุณต้องค้นหาการเกิดส่วนลดทุกอย่างในรหัสลูกค้าและเพิ่มบรรทัด

if(obj.discount>80) obj.discount = 80;

จากนั้นเจ้าของร้าน E-ต่อไปอาจมีการเปลี่ยนแปลงกลยุทธ์ของเขาเช่น"ถ้าลูกค้าเป็นผู้ค้าปลีก, ส่วนลดสูงสุดสามารถเป็น 90%" และคุณต้องทำการเปลี่ยนแปลงในหลาย ๆ สถานที่อีกครั้งและคุณต้องจำไว้ว่าต้องเปลี่ยนบรรทัดเหล่านี้ทุกครั้งที่มีการเปลี่ยนแปลงกลยุทธ์ นี่คือการออกแบบที่ไม่ดี นั่นเป็นเหตุผลที่encapsulationเป็นหลักการพื้นฐานของ OOP หากตัวสร้างเป็นเช่นนี้:

function Product(name,price) {
  var _name=name, _price=price, _discount=0;
  this.getName = function() { return _name; }
  this.setName = function(value) { _name = value; }
  this.getPrice = function() { return _price; }
  this.setPrice = function(value) { _price = value; }
  this.getDiscount = function() { return _discount; }
  this.setDiscount = function(value) { _discount = value; } 
}

จากนั้นคุณสามารถเปลี่ยนวิธีgetDiscount( accessor ) และsetDiscount( mutator ) ปัญหาคือสมาชิกส่วนใหญ่ทำตัวเหมือนตัวแปรทั่วไปเพียงแค่ส่วนลดต้องได้รับการดูแลเป็นพิเศษที่นี่ แต่การออกแบบที่ดีต้องมีการห่อหุ้มข้อมูลของสมาชิกทุกคนเพื่อให้สามารถขยายโค้ดได้ ดังนั้นคุณต้องเพิ่มโค้ดจำนวนมากที่ไม่ทำอะไรเลย นี้คือการออกแบบที่ไม่ดีantipattern สำเร็จรูป บางครั้งคุณไม่สามารถปรับเปลี่ยนเขตข้อมูลให้เป็นวิธีการในภายหลัง (รหัส eshop อาจขยายใหญ่ขึ้นหรือรหัสบุคคลที่สามบางอย่างอาจขึ้นอยู่กับรุ่นเก่า) ดังนั้นแผ่นเหล็กสำเร็จรูปจึงมีความชั่วร้ายน้อยลงที่นี่ แต่ถึงกระนั้นมันก็เป็นความชั่วร้าย นั่นเป็นสาเหตุที่คุณสมบัติถูกนำมาใช้ในหลายภาษา คุณสามารถเก็บรหัสเดิมเพียงแค่เปลี่ยนสมาชิกส่วนลดให้เป็นทรัพย์สินด้วยgetและsetบล็อก:

function Product(name,price) {
  this.name = name;
  this.price = price;
//this.discount = 0; // <- remove this line and refactor with the code below
  var _discount; // private member
  Object.defineProperty(this,"discount",{
    get: function() { return _discount; },
    set: function(value) { _discount = value; if(_discount>80) _discount = 80; }
  });
}

// the client code
var sneakers = new Product("Sneakers",20);
sneakers.discount = 50; // 50, setter is called
sneakers.discount+= 20; // 70, setter is called
sneakers.discount+= 20; // 80, not 90!
alert(sneakers.discount); // getter is called

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

มากเกี่ยวกับคุณสมบัติ แต่จาวาสคริปต์นั้นแตกต่างจากภาษาเชิงวัตถุล้วนๆเช่น C # และรหัสคุณลักษณะต่างกัน:

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

ใน Javascriptคุณสมบัติมาตรฐาน (สมาชิกข้อมูลที่มี getter และ setter อธิบายไว้ข้างต้น) ถูกกำหนดโดยตัวอธิบาย accessor (ในลิงก์ที่คุณมีในคำถามของคุณ) โดยเฉพาะคุณสามารถใช้data descriptor (ดังนั้นคุณไม่สามารถใช้ค่า ie และตั้งค่าในคุณสมบัติเดียวกัน):

  • accessor descriptor = get + set (ดูตัวอย่างด้านบน)
    • รับจะต้องมีฟังก์ชั่น; ส่งคืนค่าที่ใช้ในการอ่านคุณสมบัติ หากไม่ได้ระบุไว้ค่าเริ่มต้นจะไม่ได้กำหนดซึ่งจะทำหน้าที่เหมือนฟังก์ชันที่ส่งคืนค่าที่ไม่ได้กำหนด
    • ชุดต้องเป็นฟังก์ชั่น; พารามิเตอร์ของมันเต็มไปด้วย RHS ในการกำหนดค่าให้กับคุณสมบัติ หากไม่ได้ระบุไว้ค่าเริ่มต้นจะไม่ได้กำหนดซึ่งจะทำหน้าที่เหมือนฟังก์ชันที่ว่างเปล่า
  • data descriptor = value + ที่เขียนได้ (ดูตัวอย่างด้านล่าง)
    • ค่าเริ่มต้นไม่ได้กำหนด ; ถ้าเขียนได้ ,การกำหนดค่าและนับ (ดูด้านล่าง) เป็นจริงพฤติกรรมของสถานที่ให้บริการเช่นเขตข้อมูลสามัญ
    • เขียนได้ -เท็จเริ่มต้น; หากไม่เป็นจริงคุณสมบัติจะอ่านได้อย่างเดียว ความพยายามในการเขียนถูกละเว้นโดยไม่มีข้อผิดพลาด *!

ตัวอธิบายทั้งสองสามารถมีสมาชิกเหล่านี้:

  • กำหนดค่าได้ -เท็จเริ่มต้น; หากไม่เป็นจริงคุณสมบัติจะไม่สามารถลบได้ ความพยายามในการลบถูกละเว้นโดยไม่มีข้อผิดพลาด *!
  • นับได้ -เท็จเริ่มต้น; ถ้าเป็นจริงก็จะมีการซ้ำในfor(var i in theObject); หากเป็นเท็จจะไม่มีการทำซ้ำ แต่ยังสามารถเข้าถึงได้แบบสาธารณะ

* ยกเว้นในโหมดเข้มงวด - ในกรณีนั้น JS หยุดการดำเนินการกับ TypeError เว้นแต่ว่าจะอยู่ในบล็อก try-catch

Object.getOwnPropertyDescriptor()อ่านการตั้งค่าเหล่านี้ใช้

เรียนรู้ตามตัวอย่าง:

var o = {};
Object.defineProperty(o,"test",{
  value: "a",
  configurable: true
});
console.log(Object.getOwnPropertyDescriptor(o,"test")); // check the settings    

for(var i in o) console.log(o[i]); // nothing, o.test is not enumerable
console.log(o.test); // "a"
o.test = "b"; // o.test is still "a", (is not writable, no error)
delete(o.test); // bye bye, o.test (was configurable)
o.test = "b"; // o.test is "b"
for(var i in o) console.log(o[i]); // "b", default fields are enumerable

หากคุณไม่ต้องการให้รหัสไคลเอนต์โกงเช่นนี้คุณสามารถ จำกัด ออบเจ็กต์ด้วยการคุมขังสามระดับ:

  • Object.preventExtensions (yourObject)ป้องกันไม่ให้คุณสมบัติใหม่ที่จะเพิ่มyourObject ใช้Object.isExtensible(<yourObject>)เพื่อตรวจสอบว่ามีการใช้วิธีการนี้กับวัตถุหรือไม่ การป้องกันตื้น (อ่านด้านล่าง)
  • Object.seal (yourObject)เหมือนกับด้านบนและไม่สามารถลบคุณสมบัติได้ (ตั้งค่าconfigurable: falseเป็นคุณสมบัติทั้งหมดได้อย่างมีประสิทธิภาพ) ใช้Object.isSealed(<yourObject>)เพื่อตรวจจับคุณสมบัตินี้บนวัตถุ ตราประทับนั้นตื้น (อ่านด้านล่าง)
  • Object.freeze (yourObject)เหมือนกับด้านบนและไม่สามารถเปลี่ยนแปลงคุณสมบัติได้ (กำหนดwritable: falseให้คุณสมบัติทั้งหมดที่มี data descriptor ได้อย่างมีประสิทธิภาพ) คุณสมบัติการเขียนของ Setter ไม่ได้รับผลกระทบ (เนื่องจากไม่มี) การแช่แข็งนั้นตื้น : หมายความว่าถ้าคุณสมบัติเป็นวัตถุคุณสมบัติของมันจะไม่ถูกแช่แข็ง (ถ้าคุณต้องการคุณควรดำเนินการบางอย่างเช่น "แช่แข็งลึก" ซึ่งคล้ายกับการทำสำเนาลึก ) ใช้Object.isFrozen(<yourObject>)ในการตรวจจับ

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


ส่วนนี้มีความชัดเจน function Product(name,price) { this.name = name; this.price = price; var _discount; // private member Object.defineProperty(this,"discount",{ get: function() { return _discount; }, set: function(value) { _discount = value; if(_discount>80) _discount = 80; } }); } var sneakers = new Product("Sneakers",20); sneakers.discount = 50; // 50, setter is called sneakers.discount+= 20; // 70, setter is called sneakers.discount+= 20; // 80, not 90! alert(sneakers.discount); // getter is called
abu abu

27

getเป็นฟังก์ชั่นที่เรียกว่าเมื่อคุณพยายามที่จะอ่านค่าplayer.healthเช่นใน:

console.log(player.health);

มันมีประสิทธิภาพไม่แตกต่างจาก:

player.getHealth = function(){
  return 10 + this.level*15;
}
console.log(player.getHealth());

ตรงกันข้ามกับการได้รับการตั้งค่าซึ่งจะใช้เมื่อคุณกำหนดให้กับค่า เนื่องจากไม่มีตัวตั้งค่าดูเหมือนว่าการกำหนดให้กับสุขภาพของผู้เล่นไม่ได้มีเจตนา:

player.health = 5; // Doesn't do anything, since there is no set function defined

ตัวอย่างง่าย ๆ :

var player = {
  level: 5
};

Object.defineProperty(player, "health", {
  get: function() {
    return 10 + (player.level * 15);
  }
});

console.log(player.health); // 85
player.level++;
console.log(player.health); // 100

player.health = 5; // Does nothing
console.log(player.health); // 100


มันเหมือนกับฟังก์ชั่นที่คุณไม่จำเป็นต้องใช้()ในการโทร ... ฉันไม่เข้าใจความคิดเมื่อพวกเขาคิดค้นสิ่งนี้ ฟังก์ชั่นจะเหมือนกันทั้งหมด: jsbin.com/bugipi/edit?js,console,output
vsync

15

definePropertyเป็นวิธีการเกี่ยวกับวัตถุที่ช่วยให้คุณสามารถกำหนดค่าคุณสมบัติให้ตรงตามเกณฑ์บางอย่าง นี่คือตัวอย่างง่ายๆที่มีวัตถุพนักงานที่มีสองคุณสมบัติชื่อและนามสกุลและผนวกสองคุณสมบัติโดยการแทนที่เมธอดtoStringบนวัตถุ

var employee = {
    firstName: "Jameel",
    lastName: "Moideen"
};
employee.toString=function () {
    return this.firstName + " " + this.lastName;
};
console.log(employee.toString());

คุณจะได้ผลลัพธ์เป็น: Jameel Moideen

ฉันจะเปลี่ยนรหัสเดียวกันโดยใช้ defineProperty บนวัตถุ

var employee = {
    firstName: "Jameel",
    lastName: "Moideen"
};
Object.defineProperty(employee, 'toString', {
    value: function () {
        return this.firstName + " " + this.lastName;
    },
    writable: true,
    enumerable: true,
    configurable: true
});
console.log(employee.toString());

พารามิเตอร์แรกคือชื่อของวัตถุจากนั้นพารามิเตอร์ที่สองคือชื่อของคุณสมบัติที่เรากำลังเพิ่มในกรณีของเรามัน toString แล้วพารามิเตอร์สุดท้ายคือวัตถุ json ซึ่งมีค่าจะเป็นฟังก์ชั่นและพารามิเตอร์ที่สามสามารถเขียนได้นับได้ และสามารถกำหนดค่าได้ตอนนี้ฉันเพิ่งประกาศว่าทุกอย่างเป็นจริง

หากคุณเรียกใช้ตัวอย่างคุณจะได้รับผลลัพธ์เป็น: Jameel Moideen

มาทำความเข้าใจว่าทำไมเราถึงต้องการคุณสมบัติสามอย่างเช่นเขียนได้นับได้และกำหนดค่าได้

เขียนได้

หนึ่งในส่วนที่น่ารำคาญมากของจาวาสคริปต์คือถ้าคุณเปลี่ยนคุณสมบัติ toString เป็นอย่างอื่น

ป้อนคำอธิบายรูปภาพที่นี่

ถ้าคุณทำสิ่งนี้อีกครั้งทุกอย่างจะหยุดลง ลองเปลี่ยนเขียนเป็นเท็จ หากเรียกใช้ซ้ำอีกครั้งคุณจะได้ผลลัพธ์ที่ถูกต้องเป็น 'Jameel Moideen' คุณสมบัตินี้จะป้องกันไม่ให้เขียนทับคุณสมบัตินี้ในภายหลัง

นับ

หากคุณพิมพ์คีย์ทั้งหมดภายในวัตถุคุณสามารถดูคุณสมบัติทั้งหมดรวมถึง toString

console.log(Object.keys(employee));

ป้อนคำอธิบายรูปภาพที่นี่

ถ้าคุณตั้งค่า enumerable เป็นเท็จคุณสามารถซ่อน toString คุณสมบัติจากคนอื่น ๆ หากเรียกใช้อีกครั้งคุณจะได้รับชื่อ, นามสกุล

ที่กำหนด

ถ้ามีใครบางคนในภายหลังกำหนดวัตถุในภายหลังเช่นนับจำนวนจริงและเรียกใช้ คุณสามารถเห็นคุณสมบัติ toString มาอีกครั้ง

var employee = {
    firstName: "Jameel",
    lastName: "Moideen"
};
Object.defineProperty(employee, 'toString', {
    value: function () {
        return this.firstName + " " + this.lastName;
    },
    writable: false,
    enumerable: false,
    configurable: true
});

//change enumerable to false
Object.defineProperty(employee, 'toString', {

    enumerable: true
});
employee.toString="changed";
console.log(Object.keys(employee));

ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถ จำกัด พฤติกรรมนี้ได้โดยตั้งค่าเป็นเท็จ

การอ้างอิงดั้งเดิมของข้อมูลนี้มาจากบล็อกส่วนตัวของฉัน


1
ฉันเข้าใจว่าคุณมีสิ่งนี้ในบล็อกของคุณและเพิ่งวางมันที่นี่ แต่อย่างน้อยก็รู้สิ่งนี้ในอนาคต: screencaps ไม่ได้รับความนิยมใน SO คุณไม่สามารถคัดลอกรหัสยาสีฟันเพื่อทดลองใช้และเครื่องมือค้นหาหรือเทคโนโลยีช่วยเหลือจะไม่เห็นรหัส
Domino

@JacqueGoupil คุณพูดถูกฉันจะอัปเดตโดยเพิ่มรหัสแทนภาพหน้าจอ
Code-EZ

3

โดยทั่วไปdefinePropertyเป็นวิธีการที่ใช้ใน 3 พารามิเตอร์ - วัตถุทรัพย์สินและ descriptor สิ่งที่เกิดขึ้นในการโทรนี้โดยเฉพาะคือ"health"คุณสมบัติของplayerวัตถุได้รับมอบหมายให้ 10 และ 15 เท่าของระดับของวัตถุผู้เล่น


0

ใช่ไม่มีฟังก์ชั่นเพิ่มเติมสำหรับการตั้งค่า setter & getter นี่คือตัวอย่างของฉันObject.defineProperty (obj, ชื่อ, func)

var obj = {};
['data', 'name'].forEach(function(name) {
    Object.defineProperty(obj, name, {
        get : function() {
            return 'setter & getter';
        }
    });
});


console.log(obj.data);
console.log(obj.name);

0

Object.defineProperty () เป็นฟังก์ชั่นระดับโลก .. มันไม่สามารถใช้ได้ภายในฟังก์ชั่นที่ประกาศวัตถุอื่นคุณจะต้องใช้มันแบบคงที่ ...


0

สรุป:

Object.defineProperty(player, "health", {
    get: function () {
        return 10 + ( player.level * 15 );
    }
});

Object.definePropertyถูกใช้เพื่อสร้างคุณสมบัติใหม่บนวัตถุผู้เล่น Object.definePropertyเป็นฟังก์ชันที่มีอยู่ใน JS runtime environemnt และรับอาร์กิวเมนต์ต่อไปนี้:

Object.defineProperty(obj, prop, descriptor)

  1. วัตถุที่เราต้องการกำหนดคุณสมบัติใหม่
  2. ชื่อของคุณสมบัติใหม่ที่เราต้องการที่จะกำหนด
  3. วัตถุอธิบาย

วัตถุ descriptor เป็นส่วนที่น่าสนใจ ที่นี่เราสามารถกำหนดสิ่งต่อไปนี้:

  1. กำหนดค่าได้ <boolean> : หากtrue ตัวบอกคุณสมบัติอาจมีการเปลี่ยนแปลงและคุณสมบัติอาจถูกลบออกจากวัตถุ หากกำหนดได้คือfalseคุณสมบัติตัวให้คำอธิบายที่Object.definePropertyไม่สามารถเปลี่ยนได้
  2. เขียนได้ <boolean> : หากtrueทรัพย์สินอาจถูกเขียนทับโดยใช้ผู้ประกอบการที่ได้รับมอบหมาย
  3. นับได้ <boolean> : ถ้าtrue คุณสมบัติสามารถวนซ้ำในfor...inลูป นอกจากนี้เมื่อใช้Object.keysฟังก์ชันปุ่มจะปรากฏขึ้น ถ้าคุณสมบัติคือfalseพวกเขาจะไม่ซ้ำมากกว่าใช้ห่วงและไม่แสดงขึ้นเมื่อใช้for..inObject.keys
  4. รับ <function> : ฟังก์ชั่นที่เรียกว่าเมื่อใดก็ตามที่เป็นคุณสมบัติที่จำเป็น แทนที่จะให้ค่าโดยตรงฟังก์ชันนี้เรียกว่าและค่าที่ส่งคืนจะได้รับเป็นค่าของคุณสมบัติ
  5. set <function> : ฟังก์ชั่นที่เรียกว่าเมื่อใดก็ตามที่มีการกำหนดคุณสมบัติ แทนที่จะตั้งค่าโดยตรงฟังก์ชั่นนี้เรียกว่าและใช้ค่าที่ส่งคืนเพื่อตั้งค่าของคุณสมบัติ

ตัวอย่าง:

const player = {
  level: 10
};

Object.defineProperty(player, "health", {
  configurable: true,
  enumerable: false,
  get: function() {
    console.log('Inside the get function');
    return 10 + (player.level * 15);
  }
});

console.log(player.health);
// the get function is called and the return value is returned as a value

for (let prop in player) {
  console.log(prop);
  // only prop is logged here, health is not logged because is not an iterable property.
  // This is because we set the enumerable to false when defining the property
}


0

import { CSSProperties } from 'react'
import { BLACK, BLUE, GREY_DARK, WHITE } from '../colours'

export const COLOR_ACCENT = BLUE
export const COLOR_DEFAULT = BLACK
export const FAMILY = "'Segoe UI', sans-serif"
export const SIZE_LARGE = '26px'
export const SIZE_MEDIUM = '20px'
export const WEIGHT = 400

type Font = {
  color: string,
  size: string,
  accent: Font,
  default: Font,
  light: Font,
  neutral: Font,
  xsmall: Font,
  small: Font,
  medium: Font,
  large: Font,
  xlarge: Font,
  xxlarge: Font
} & (() => CSSProperties)

function font (this: Font): CSSProperties {
  const css = {
    color: this.color,
    fontFamily: FAMILY,
    fontSize: this.size,
    fontWeight: WEIGHT
  }
  delete this.color
  delete this.size
  return css
}

const dp = (type: 'color' | 'size', name: string, value: string) => {
  Object.defineProperty(font, name, { get () {
    this[type] = value
    return this
  }})
}

dp('color', 'accent', COLOR_ACCENT)
dp('color', 'default', COLOR_DEFAULT)
dp('color', 'light', COLOR_LIGHT)
dp('color', 'neutral', COLOR_NEUTRAL)
dp('size', 'xsmall', SIZE_XSMALL)
dp('size', 'small', SIZE_SMALL)
dp('size', 'medium', SIZE_MEDIUM)

export default font as Font


0

กำหนดคุณสมบัติใหม่โดยตรงบนวัตถุหรือปรับเปลี่ยนคุณสมบัติที่มีอยู่บนวัตถุและส่งคืนวัตถุ

หมายเหตุ: คุณเรียกเมธอดนี้โดยตรงบนตัวสร้างวัตถุแทนที่จะเป็นอินสแตนซ์ของชนิดวัตถุ

   const object1 = {};
   Object.defineProperty(object1, 'property1', {
      value: 42,
      writable: false, //If its false can't modify value using equal symbol
      enumerable: false, // If its false can't able to get value in Object.keys and for in loop
      configurable: false //if its false, can't able to modify value using defineproperty while writable in false
   });

ป้อนคำอธิบายรูปภาพที่นี่

คำอธิบายง่ายๆเกี่ยวกับกำหนดคุณสมบัติ

รหัสตัวอย่าง: https://jsfiddle.net/manoj_antony32/pu5n61fs/


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.