[译]因扩展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()的第二个参数中也有属性描述符对象,也有可能出现同样的问题.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值