Object.defineProperty()
åºçº¿
广æ³å¯ç¨
èª 2015å¹´7æ èµ·ï¼æ¤ç¹æ§å·²å¨ä¸»æµæµè§å¨ä¸å¾å°æ¯æï¼å¯å¨å¤§å¤æ°è®¾å¤åæµè§å¨çæ¬ä¸æ£å¸¸ä½¿ç¨ã
Object.defineProperty() éææ¹æ³ä¼ç´æ¥å¨ä¸ä¸ªå¯¹è±¡ä¸å®ä¹ä¸ä¸ªæ°å±æ§ï¼æä¿®æ¹å
¶ç°æå±æ§ï¼å¹¶è¿åæ¤å¯¹è±¡ã
å°è¯ä¸ä¸
const object1 = {};
Object.defineProperty(object1, "property1", {
value: 42,
writable: false,
});
object1.property1 = 77;
// Throws an error in strict mode
console.log(object1.property1);
// Expected output: 42
è¯æ³
Object.defineProperty(obj, prop, descriptor)
åæ°
obj-
è¦å®ä¹å±æ§ç对象ã
prop-
ä¸ä¸ªå符串æ
Symbolï¼æå®äºè¦å®ä¹æä¿®æ¹ç屿§é®ã descriptor-
è¦å®ä¹æä¿®æ¹ç屿§çæè¿°ç¬¦ã
è¿åå¼
ä¼ å ¥å½æ°ç对象ï¼å ¶æå®ç屿§å·²è¢«æ·»å æä¿®æ¹ã
æè¿°
Object.defineProperty() å
è®¸ç²¾ç¡®å°æ·»å æä¿®æ¹å¯¹è±¡ä¸ç屿§ãéè¿èµå¼æ·»å çæ®é屿§ä¼å¨æä¸¾å±æ§æ¶ï¼ä¾å¦ for...inãObject.keys() çï¼åºç°ï¼å®ä»¬çå¼å¯ä»¥è¢«æ´æ¹ï¼ä¹å¯ä»¥è¢«å é¤ãæ¤æ¹æ³å
è®¸æ´æ¹è¿äºé¢å¤ç»èï¼ä»¥ä½¿å
¶ä¸åäºé»è®¤å¼ãé»è®¤æ
åµä¸ï¼ä½¿ç¨ Object.defineProperty() æ·»å ç屿§æ¯ä¸å¯åãä¸å¯æä¸¾åä¸å¯é
ç½®çãæ¤å¤ï¼Object.defineProperty() ä½¿ç¨ [[DefineOwnProperty]] å
鍿¹æ³ï¼è䏿¯ [[Set]]ï¼å æ¤å³ä½¿å±æ§å·²ç»åå¨ï¼å®ä¹ä¸ä¼è°ç¨ setterã
对象ä¸åå¨ç屿§æè¿°ç¬¦æä¸¤ç§ä¸»è¦ç±»åï¼æ°æ®æè¿°ç¬¦å访é®å¨æè¿°ç¬¦ãæ°æ®æè¿°ç¬¦æ¯ä¸ä¸ªå ·æå¯åæä¸å¯åå¼ç屿§ã访é®å¨æè¿°ç¬¦æ¯ç± getter/setter 彿°å¯¹æè¿°ç屿§ãæè¿°ç¬¦åªè½æ¯è¿ä¸¤ç§ç±»åä¹ä¸ï¼ä¸è½åæ¶ä¸ºä¸¤è ã
æ°æ®æè¿°ç¬¦å访é®å¨æè¿°ç¬¦é½æ¯å¯¹è±¡ãå®ä»¬å
±äº«ä»¥ä¸å¯éé®ï¼è¯·æ³¨æï¼å¨ä½¿ç¨ Object.defineProperty() å®ä¹å±æ§çæ
åµä¸ï¼ä¸è¿°ææé®é½æ¯é»è®¤å¼ï¼ï¼
configurable-
å½è®¾ç½®ä¸º
falseæ¶ï¼- è¯¥å±æ§çç±»åä¸è½å¨æ°æ®å±æ§å访é®å¨å±æ§ä¹é´æ´æ¹ï¼ä¸
- è¯¥å±æ§ä¸å¯è¢«å é¤ï¼ä¸
- å
¶æè¿°ç¬¦çå
¶ä»å±æ§ä¹ä¸è½è¢«æ´æ¹ï¼ä½æ¯ï¼å¦æå®æ¯ä¸ä¸ªå¯åçæ°æ®æè¿°ç¬¦ï¼å
valueå¯ä»¥è¢«æ´æ¹ï¼writableå¯ä»¥æ´æ¹ä¸ºfalseï¼ã
é»è®¤å¼ä¸º
falseã enumerable-
å½ä¸ä» å½è¯¥å±æ§å¨å¯¹åºå¯¹è±¡ç屿§æä¸¾ä¸åºç°æ¶ï¼å¼ä¸º
trueãé»è®¤å¼ä¸ºfalseã
æ°æ®æè¿°ç¬¦è¿å ·æä»¥ä¸å¯éé®å¼ï¼
value-
ä¸å±æ§ç¸å ³èçå¼ãå¯ä»¥æ¯ä»»ä½ææç JavaScript å¼ï¼æ°åã对象ã彿°çï¼ãé»è®¤å¼ä¸º
undefinedã writable-
妿ä¸å±æ§ç¸å ³èçå¼å¯ä»¥ä½¿ç¨èµå¼è¿ç®ç¬¦æ´æ¹ï¼å为
trueãé»è®¤å¼ä¸ºfalseã
访é®å¨æè¿°ç¬¦è¿å ·æä»¥ä¸å¯éé®å¼ï¼
get-
ç¨ä½å±æ§ getter ç彿°ï¼å¦ææ²¡æ getter å为
undefinedãå½è®¿é®è¯¥å±æ§æ¶ï¼å°ä¸å¸¦åå°è°ç¨æ¤å½æ°ï¼å¹¶å°this设置为éè¿è¯¥å±æ§è®¿é®ç对象ï¼å 为å¯è½åå¨ç»§æ¿å ³ç³»ï¼è¿å¯è½ä¸æ¯å®ä¹è¯¥å±æ§ç对象ï¼ãè¿åå¼å°è¢«ç¨ä½è¯¥å±æ§çå¼ãé»è®¤å¼ä¸ºundefinedã set-
ç¨ä½å±æ§ setter ç彿°ï¼å¦ææ²¡æ setter å为
undefinedãå½è¯¥å±æ§è¢«èµå¼æ¶ï¼å°è°ç¨æ¤å½æ°ï¼å¹¶å¸¦æä¸ä¸ªåæ°ï¼è¦èµç»è¯¥å±æ§çå¼ï¼ï¼å¹¶å°this设置为éè¿è¯¥å±æ§åé ç对象ãé»è®¤å¼ä¸ºundefinedã
妿æè¿°ç¬¦æ²¡æ valueãwritableãget å set é®ä¸çä»»ä½ä¸ä¸ªï¼å®å°è¢«è§ä¸ºæ°æ®æè¿°ç¬¦ã妿æè¿°ç¬¦åæ¶å
·æ [value æ writable] å [get æ set] é®ï¼å伿åºå¼å¸¸ã
è¿äºå±æ§ä¸ä¸å®æ¯æè¿°ç¬¦æ¬èº«ç屿§ãç»§æ¿ç屿§ä¹ä¼è¢«èèå¨å
ã为äºç¡®ä¿è¿äºé»è®¤å¼å¾å°ä¿çï¼ä½ å¯ä»¥é¢å
å»ç»æè¿°ç¬¦å¯¹è±¡ååé¾ä¸çç°æå¯¹è±¡ï¼æç¡®æå®ææéé¡¹ï¼æä½¿ç¨ Object.create(null) æå nullã
const obj = {};
// 1. ä½¿ç¨ null ååï¼æ²¡æç»§æ¿ç屿§
const descriptor = Object.create(null);
descriptor.value = "static";
// é»è®¤æ
åµä¸ï¼å®ä»¬ä¸å¯æä¸¾ãä¸å¯é
ç½®ãä¸å¯å
Object.defineProperty(obj, "key", descriptor);
// 2. 使ç¨ä¸ä¸ªå
嫿æå±æ§ç临æ¶å¯¹è±¡åé¢éæ¥æç¡®å
¶å±æ§
Object.defineProperty(obj, "key2", {
enumerable: false,
configurable: false,
writable: false,
value: "static",
});
// 3. éå¤å©ç¨åä¸å¯¹è±¡
function withValue(value) {
const d =
withValue.d ||
(withValue.d = {
enumerable: false,
writable: false,
configurable: false,
value,
});
// é¿å
éå¤èµå¼
if (d.value !== value) d.value = value;
return d;
}
// ç¶å
Object.defineProperty(obj, "key", withValue("static"));
// 妿 freeze å¯ç¨ï¼é²æ¢æ·»å æå é¤å¯¹è±¡åå屿§
// ï¼valueãgetãsetãenumerableãwritableãconfigurableï¼
(Object.freeze || Object)(Object.prototype);
å½å±æ§å·²ç»å卿¶ï¼Object.defineProperty() ä¼å°è¯æ ¹æ®æè¿°ç¬¦å屿§çå½åé
置修æ¹å±æ§ã
å¦ææ§æè¿°ç¬¦ç configurable ç¹æ§è¢«è®¾ç½®ä¸º falseï¼åè¯¥å±æ§è¢«ç§°ä¸ºä¸å¯é
ç½®çãæ æ³æ´æ¹ä¸å¯é
ç½®ç访é®å¨å±æ§çä»»ä½ç¹æ§ï¼ä¹ä¸è½å°å
¶å¨æ°æ®ç±»åå访é®å¨ç±»åä¹é´åæ¢ã对äºå
·æ writable: true çæ°æ®å±æ§ï¼å¯ä»¥ä¿®æ¹å
¶å¼å¹¶å° writable ç¹æ§ä» true æ¹ä¸º falseãå½è¯å¾æ´æ¹ä¸å¯é
ç½®ç屿§ï¼é¤éå
è®¸æ´æ¹ value å writableï¼æ¶ï¼ä¼æåº TypeErrorï¼é¤é卿°æ®å±æ§ä¸å®ä¹ä¸ä¸ªä¸åå§å¼ç¸åçå¼ã
å½å½å屿§æ¯å¯é
ç½®çæ¶ï¼å°ç¹æ§è®¾ç½®ä¸º undefined å¯ä»¥ææå°å é¤å®ãä¾å¦ï¼å¦æ o.k æ¯ä¸ä¸ªè®¿é®å¨å±æ§ï¼Object.defineProperty(o, "k", { set: undefined }) å°å é¤ setterï¼ä½¿ k åªæ getter å¹¶åæåªè¯»çãå¦ææ°æè¿°ç¬¦ä¸ç¼ºå°ä¸ä¸ªç¹æ§ï¼åä¼ä¿çæ§æè¿°ç¬¦è¯¥ç¹æ§çå¼ï¼ä¸ä¼è¢«éå¼éæ°è®¾ç½®ä¸º undefinedï¼ãéè¿æä¾ä¸åç±»åçæè¿°ç¬¦ï¼å¯ä»¥å¨æ°æ®å±æ§å访é®å¨å±æ§ä¹é´åæ¢ãä¾å¦ï¼å¦ææ°æè¿°ç¬¦æ¯æ°æ®æè¿°ç¬¦ï¼å¸¦æ value æ writableï¼ï¼ååå§æè¿°ç¬¦ç get å set 屿§é½å°è¢«å é¤ã
示ä¾
>åå»ºå±æ§
å½å¯¹è±¡ä¸ä¸å卿å®ç屿§æ¶ï¼Object.defineProperty() å°æ ¹æ®æè¿°ç¬¦å建ä¸ä¸ªæ°ç屿§ãæè¿°ç¬¦ä¸çåæ®µå¯ä»¥çç¥ï¼çç¥çåæ®µå°ä½¿ç¨é»è®¤å¼ã
const o = {}; // å建ä¸ä¸ªæ°å¯¹è±¡
// éè¿ defineProperty ä½¿ç¨æ°æ®æè¿°ç¬¦æ·»å å¯¹è±¡å±æ§ç示ä¾
Object.defineProperty(o, "a", {
value: 37,
writable: true,
enumerable: true,
configurable: true,
});
// 'a' 屿§åå¨äºå¯¹è±¡ o ä¸ï¼å
¶å¼ä¸º 37
// éè¿ defineProperty 使ç¨è®¿é®å¨å±æ§æè¿°ç¬¦æ·»å å¯¹è±¡å±æ§ç示ä¾
let bValue = 38;
Object.defineProperty(o, "b", {
get() {
return bValue;
},
set(newValue) {
bValue = newValue;
},
enumerable: true,
configurable: true,
});
o.b; // 38
// 'b' 屿§åå¨äºå¯¹è±¡ o ä¸ï¼å
¶å¼ä¸º 38ã
// o.b çå¼ç°å¨å§ç»ä¸ bValue ç¸åï¼é¤ééæ°å®ä¹äº o.bã
// æ°æ®æè¿°ç¬¦å访é®å¨æè¿°ç¬¦ä¸è½æ··å使ç¨
Object.defineProperty(o, "conflict", {
value: 0x9f91102,
get() {
return 0xdeadbeef;
},
});
// æåºé误 TypeError: value appears only in data descriptors, get appears only in accessor descriptors
ä¿®æ¹å±æ§
å½ä¿®æ¹å·²åå¨ç屿§æ¶ï¼æä½çç»æåå³äºå½å屿§çé
ç½®ï¼å¯è½ä¼æåã䏿§è¡ä»»ä½æä½ï¼ææåºä¸ä¸ª TypeError å¼å¸¸ã
Writable ç¹æ§
å½ writable ç¹æ§è®¾ç½®ä¸º false æ¶ï¼è¯¥å±æ§è¢«ç§°ä¸ºâä¸å¯åçâãå®ä¸è½è¢«éæ°èµå¼ãå°è¯å¯¹ä¸ä¸ªä¸å¯åç屿§è¿è¡åå
¥ä¸ä¼æ¹åå®ï¼å¨ä¸¥æ ¼æ¨¡å¼ä¸è¿ä¼å¯¼è´é误ã
const o = {}; // å建ä¸ä¸ªæ°å¯¹è±¡
Object.defineProperty(o, "a", {
value: 37,
writable: false,
});
console.log(o.a); // 37
o.a = 25; // ä¸ä¼æåºé误
// ï¼å¨ä¸¥æ ¼æ¨¡å¼ä¸ï¼å³ä½¿å¼ç¸åï¼å®ä¹ä¼æåºå¼å¸¸ï¼
console.log(o.a); // 37ï¼èµå¼ä¸ä¼æå
// ä¸¥æ ¼æ¨¡å¼
(() => {
"use strict";
const o = {};
Object.defineProperty(o, "b", {
value: 2,
writable: false,
});
o.b = 3; // æåº TypeError: "b" is read-only
return o.b; // å¦ææ²¡æä¸ä¸è¡çè¯ï¼ä¼è¿å 2
})();
Enumerable ç¹æ§
enumerable ç¹æ§å®ä¹äºå±æ§æ¯å¦å¯ä»¥è¢« Object.assign() æå±å¼è¿ç®ç¬¦æèèã对äºé Symbol 屿§ï¼å®è¿å®ä¹äºå±æ§æ¯å¦ä¼å¨ for...in 循ç¯å Object.keys() 䏿¾ç¤ºãæ´å¤ä¿¡æ¯ï¼è¯·åè§å±æ§çæä¸¾æ§åæææã
const o = {};
Object.defineProperty(o, "a", {
value: 1,
enumerable: true,
});
Object.defineProperty(o, "b", {
value: 2,
enumerable: false,
});
Object.defineProperty(o, "c", {
value: 3,
}); // enumerable é»è®¤ä¸º false
o.d = 4; // éè¿èµå¼åå»ºå±æ§æ¶ enumerable é»è®¤ä¸º true
Object.defineProperty(o, Symbol.for("e"), {
value: 5,
enumerable: true,
});
Object.defineProperty(o, Symbol.for("f"), {
value: 6,
enumerable: false,
});
for (const i in o) {
console.log(i);
}
// æå° 'a' å 'd'ï¼æ»æ¯æè¿ä¸ªé¡ºåºï¼
Object.keys(o); // ['a', 'd']
o.propertyIsEnumerable("a"); // true
o.propertyIsEnumerable("b"); // false
o.propertyIsEnumerable("c"); // false
o.propertyIsEnumerable("d"); // true
o.propertyIsEnumerable(Symbol.for("e")); // true
o.propertyIsEnumerable(Symbol.for("f")); // false
const p = { ...o };
p.a; // 1
p.b; // undefined
p.c; // undefined
p.d; // 4
p[Symbol.for("e")]; // 5
p[Symbol.for("f")]; // undefined
Configurable ç¹æ§
configurable ç¹æ§æ§å¶å±æ§æ¯å¦å¯ä»¥ä»å¯¹è±¡ä¸å é¤ä»¥åå
¶ç¹æ§ï¼é¤äº value å writableï¼æ¯å¦å¯ä»¥æ´æ¹ã
以ä¸ç¤ºä¾æ¼ç¤ºäºä¸ä¸ªä¸å¯é ç½®ç访é®å¨å±æ§ã
const o = {};
Object.defineProperty(o, "a", {
get() {
return 1;
},
configurable: false,
});
Object.defineProperty(o, "a", {
configurable: true,
}); // æåº TypeError
Object.defineProperty(o, "a", {
enumerable: true,
}); // æåº TypeError
Object.defineProperty(o, "a", {
set() {},
}); // æåº TypeErrorï¼set å¨ä¹åæªå®ä¹ï¼
Object.defineProperty(o, "a", {
get() {
return 1;
},
}); // æåº TypeError
// ï¼å³ä½¿æ°ç get åçäºæ
å®å
¨ç¸åï¼
Object.defineProperty(o, "a", {
value: 12,
}); // æåº TypeError
// âvalueâåªæå¨ writable 为 true æ¶æå¯ä»¥è¢«ä¿®æ¹
console.log(o.a); // 1
delete o.a; // æ æ³å é¤ï¼ä¸¥æ ¼æ¨¡å¼ä¸ä¼æåºé误
console.log(o.a); // 1
妿 o.a ç configurable ç¹æ§ä¸º trueï¼åä¸ä¼æåºä»»ä½é误ï¼å¹¶ä¸è¯¥å±æ§ä¼å¨æå被å é¤ã
以ä¸ç¤ºä¾è¯´æäºä¸ä¸ªä¸å¯é
ç½®ä½å¯åçæ°æ®å±æ§ãè¯¥å±æ§ç value ä»ç¶å¯ä»¥è¢«æ´æ¹ï¼writable ä¹ä»ç¶å¯ä»¥ä» true åæ¢å° falseã
const o = {};
Object.defineProperty(o, "b", {
writable: true,
configurable: false,
});
console.log(o.b); // undefined
Object.defineProperty(o, "b", {
value: 1,
}); // å³ä½¿ configurable 为 falseï¼å 为对象æ¯å¯åçï¼æä»¬ä»ç¶å¯ä»¥æ¿æ¢å±æ§çå¼ã
console.log(o.b); // 1
o.b = 2; // æä»¬ä¹å¯ä»¥ä½¿ç¨èµå¼è¿ç®ç¬¦æ¥æ´æ¹å±æ§çå¼
console.log(o.b); // 2
// 忢屿§çå¯åæ§
Object.defineProperty(o, "b", {
writable: false,
});
Object.defineProperty(o, "b", {
value: 1,
}); // TypeError: because the property is neither writable nor configurable, it cannot be modified
// æ¤æ¶ï¼æ æ³å次修æ¹å±æ§ 'b' æè
æ¢å¤å®çå¯åæ§ã
è¿ä¸ªç¤ºä¾æ¼ç¤ºäºä¸ä¸ªå¯é
ç½®ä½ä¸å¯åçæ°æ®å±æ§ãè¯¥å±æ§ç value ä»ç¶å¯ä»¥ä½¿ç¨ defineProperty è¿è¡æ¿æ¢ï¼ä½ä¸è½ä½¿ç¨èµå¼è¿ç®ç¬¦ï¼ï¼å¹¶ä¸ writable ç¹æ§ä»ç¶å¯ä»¥åæ¢ã
const o = {};
Object.defineProperty(o, "b", {
writable: false,
configurable: true,
});
Object.defineProperty(o, "b", {
value: 1,
}); // æä»¬å¯ä»¥ä½¿ç¨ defineProperty æ¹æ³æ¿æ¢å±æ§çå¼
console.log(o.b); // 1
o.b = 2; // å¨ä¸¥æ ¼æ¨¡å¼ä¸æåº TypeErrorï¼cannot change a non-writable property's value with assignment
è¿ä¸ªç¤ºä¾æ¼ç¤ºäºä¸ä¸ªä¸å¯é
ç½®ä¸ä¸å¯åçæ°æ®å±æ§ãæ æ³æ´æ°è¯¥å±æ§çä»»ä½ç¹æ§ï¼å
æ¬å®ç value å¼ã
const o = {};
Object.defineProperty(o, "b", {
writable: false,
configurable: false,
});
Object.defineProperty(o, "b", {
value: 1,
}); // TypeError: the property cannot be modified because it is neither writable nor configurable.
æ·»å å¤ä¸ªå±æ§åé»è®¤å¼
èè屿§é»è®¤å¼åºç¨çæ¹å¼æ¯é常éè¦çãé常ï¼å¨ä½¿ç¨å±æ§è®¿é®å¨åé
ä¸ä¸ªå¼åä½¿ç¨ Object.defineProperty() ä¹é´åå¨å·®å¼ï¼å¦ä¸é¢çç¤ºä¾æç¤ºã
const o = {};
o.a = 1;
// çä»·äºï¼
Object.defineProperty(o, "a", {
value: 1,
writable: true,
configurable: true,
enumerable: true,
});
// å¦ä¸ç§æ
åµ
Object.defineProperty(o, "a", { value: 1 });
// çä»·äºï¼
Object.defineProperty(o, "a", {
value: 1,
writable: false,
configurable: false,
enumerable: false,
});
èªå®ä¹ setter å getter
ä¸é¢çä¾åå±ç¤ºäºå¦ä½å®ç°ä¸ä¸ªèªå档对象ãå½è®¾ç½® temperature 屿§æ¶ï¼archive æ°ç»ä¼æ¶å°æ¥å¿æ¡ç®ã
function Archiver() {
let temperature = null;
const archive = [];
Object.defineProperty(this, "temperature", {
get() {
console.log("get!");
return temperature;
},
set(value) {
temperature = value;
archive.push({ val: temperature });
},
});
this.getArchive = () => archive;
}
const arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
ä¸é¢è¿ä¸ªä¾åä¸ï¼getter æ»æ¯ä¼è¿åä¸ä¸ªç¸åçå¼ã
const pattern = {
get() {
return "ææ»æ¯è¿åè¿ä¸ªåç¬¦ä¸²ï¼æ è®ºä½ çèµå¼æ¯ä»ä¹";
},
set() {
this.myname = "è¿æ¯æåç§°çå符串";
},
};
function TestDefineSetAndGet() {
Object.defineProperty(this, "myproperty", pattern);
}
const instance = new TestDefineSetAndGet();
instance.myproperty = "test";
console.log(instance.myproperty);
// ææ»æ¯è¿åè¿ä¸ªåç¬¦ä¸²ï¼æ è®ºä½ çèµå¼æ¯ä»ä¹
console.log(instance.myname); // è¿æ¯æåç§°çå符串
ç»§æ¿å±æ§
å¦æè®¿é®å¨å±æ§è¢«ç»§æ¿ï¼å®ç get å set æ¹æ³ä¼å¨æ´¾ç对象ç屿§è¢«è®¿é®æè
ä¿®æ¹æ¶è¢«è°ç¨ã妿è¿äºæ¹æ³ç¨ä¸ä¸ªåéåå¼ï¼è¯¥å¼ä¼è¢«ææå¯¹è±¡å
±äº«ã
function MyClass() {}
let value;
Object.defineProperty(MyClass.prototype, "x", {
get() {
return value;
},
set(x) {
value = x;
},
});
const a = new MyClass();
const b = new MyClass();
a.x = 1;
console.log(b.x); // 1
è¿å¯ä»¥éè¿å°å¼åå¨å¨å¦ä¸ä¸ªå±æ§ä¸è§£å³ãå¨ get å set æ¹æ³ä¸ï¼this æåæä¸ªè¢«è®¿é®åä¿®æ¹å±æ§ç对象ã
function MyClass() {}
Object.defineProperty(MyClass.prototype, "x", {
get() {
return this.storedX;
},
set(x) {
this.storedX = x;
},
});
const a = new MyClass();
const b = new MyClass();
a.x = 1;
console.log(b.x); // undefined
ä¸è®¿é®å¨å±æ§ä¸åï¼æ°æ®å±æ§å§ç»å¨å¯¹è±¡èªèº«ä¸è®¾ç½®ï¼è䏿¯ä¸ä¸ªååãç¶èï¼å¦æä¸ä¸ªä¸å¯åç屿§è¢«ç»§æ¿ï¼å®ä»ç¶å¯ä»¥é²æ¢ä¿®æ¹å¯¹è±¡ç屿§ã
function MyClass() {}
MyClass.prototype.x = 1;
Object.defineProperty(MyClass.prototype, "y", {
writable: false,
value: 1,
});
const a = new MyClass();
a.x = 2;
console.log(a.x); // 2
console.log(MyClass.prototype.x); // 1
a.y = 2; // 没æä½ç¨ï¼ä¸¥æ ¼æ¨¡å¼ä¸ä¼æ¥é
console.log(a.y); // 1
console.log(MyClass.prototype.y); // 1
è§è
| è§è |
|---|
| ECMAScript® 2027 Language Specification> # sec-object.defineproperty> |