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

  • 相关阅读:
    Linux常用命令英文全称与中文解释
    输入一个URL之后发生了什么?
    四种基本的数据结构
    关于深拷贝
    TCP的三次握手和四次挥手
    利用正则表达式去掉字符串的前后空格
    用canvas画一个等腰三角形
    三种隐藏元素方法的区别
    消息中间件-activemq安全机制
    Netty学习(十)-Netty文件上传
  • 原文地址:https://www.cnblogs.com/ziyunfei/p/2799984.html
Copyright © 2011-2022 走看看