[譯]因擴展Object.prototype而引發Object.defineProperty不可用的一個問題


原文:http://d.hatena.ne.jp/teramako/20121129/p1


ES-Discuss郵件列表中看到的.

Object.prototype.get = function(){};
var o = {};
Object.defineProperty(o, "hoge", { value: "OK" });
// TypeError: property descriptors must not specify a value or be writable when a getter or setter has been specified

問題描述就是:如果在Object.prototype上添加了名為get,set之類的屬性的話,再執行Object.defineProperty()的時候就很有可能發生問題.為什么?

不應該在Object.prototype上添加的屬性

下面給出的屬性名最不應該添加在Object.prototype上

  • get
  • set
  • value
  • writable

為什么?

Object.defineProperty的第三個參數Descriptor是個對象,指定了所定義屬性的屬性描述符.屬性描述符一共有兩種.數據屬性描述符(DataDescriptor)和訪問器屬性描述(AccessorDescriptor).

數據屬性描述符對象上不能有get,set屬性,訪問器屬性描述符對象上不能有value,writable屬性.

執行defineProperty的時候,在判斷屬性描述符對象中某個屬性是否存在時使用的內部方法是[[HasProperty]].[[HasProperty]]會在[[Prototype]]上尋找屬性,也就找到了Object.prototype上定義的那些屬性.如果使用[[GetOwnProperty]]來判斷的話就不會有這樣的問題了.

上例中的問題就是,get和value兩個屬性不能同時存在,否則會報錯.

解決辦法

創建一個沒有原型的屬性描述符對象:

var des = Object.create(null);
des.value = 123;
Object.defineProperty(obj,"key",des);

也可以使用非標准的魔法屬性__proto__:

Object.defineProperty(obj, "key", {
  __proto__: null,
value: 123
});

同樣,Object.defineProperties()以及Object.create()的第二個參數中也有屬性描述符對象,也有可能出現同樣的問題.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM