【问题标题】:Object.defineProperty in ES5?ES5 中的 Object.defineProperty?
【发布时间】:2011-04-19 08:24:48
【问题描述】:

我看到了有关“新”Object.create 的帖子,它使枚举可配置。但是,它依赖于 Object.defineProperty 方法。我找不到此方法的跨浏览器实现。

我们是否还在为旧的 Object.create 编写代码?我无法编写在 IE6/7 中不起作用的东西。

【问题讨论】:

    标签: javascript ecma262 prototypal-inheritance ecmascript-5


    【解决方案1】:

    在 ECMAScript 3 环境中,您无法通过 ECMAScript 5 Object.create 方法模拟一些事情。

    如您所见,properties 参数会给您带来问题,因为在基于 E3 的实现中,无法更改属性属性。

    @Raynos 提到的Object.defineProperty 方法适用于 IE8,但部分只能在 DOM 元素中使用

    另外,访问器属性会给你带来问题,它们可能被广泛支持的非标准方法模仿,例如__defineGetter__/__defineSetter__,但同样,你无法更改属性属性

    除了属性描述符之外的另一个问题是Object.create 方法可以接受null 作为参数,以创建一个不从任何东西继承的对象。

    这不能用Crockford's Object.create shim 模拟,因为当new 运算符与具有prototype 属性的构造函数一起使用时,该属性包含null - 或任何其他非对象值-,默认情况下,新创建的对象无论如何都会从Object.prototype 继承。

    在某些实现中 -V8、Spidermonkey、Rhino 等...- 它们具有可设置的 __proto__ 属性,可用于设置 null [[Prototype]],但同样,这是非标准的,并且肯定它永远不会在 IE 上运行。

    如果您想让旧浏览器不使用这些功能,我建议您不要使用这些功能,因为没有办法让它们在这些环境中正常工作。

    如果你仍然想使用Object.create,而不使用properties 参数,你可以,但是我建议你检测无法模拟的东西。

    以下是Crockford's Object.create shim更安全 版本:

    if (typeof Object.create != 'function') {
      (function () {
        var F = function () {};
        Object.create = function (o) {
          if (arguments.length > 1) { throw Error('Second argument not supported');}
          if (o === null) { throw Error('Cannot set a null [[Prototype]]');}
          if (typeof o != 'object') { throw TypeError('Argument must be an object');}
          F.prototype = o;
          return new F;
        };
      })();
    }
    

    无论如何,请谨慎使用。

    【讨论】:

      【解决方案2】:

      如果您想要一个好的defineProperty() 实现,请查看https://github.com/kriskowal/es5-shim

      不幸的是,您不能在 ES3 环境中使枚举可配置。此 shim 将允许您在任一环境中调用 API,但在 ES3 下属性仍可枚举。

      【讨论】:

        【解决方案3】:

        物有所值,

        Object.defineProperty 适用于 ie8 和 FF4。

        这意味着值得为嗅探提供特性并在有用的地方实现它,因为您希望在未来几年内从 ie 6/7 升级到 8/9。

        另外需要注意的是 dontEnum 属性在JScript 中有一个错误

        您将不得不解决在 IE 中使用 dontEnum 属性的方式。

        [编辑]:

        这是Internet explorer 的文档和ES5 specification 的链接(第 122 页,15.2.3.6)

        【讨论】:

        • 很高兴知道它在 IE8 中,我看到了可能是一个实现的一瞥。所以,我的问题仍然是是否有已发布的 defineProperty 实现?
        • 恐怕ie6/7没有这样的实现。
        • @Drew: Object.defineProperty 部分 IE8,你只能在DOM元素上使用它。我留下了answer,简而言之:你不能。属性属性不能在基于 ECMAScript 3 的实现上定义......
        • 我什至没有注意到它只适用于 DOM 元素。感谢您指出这一点。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-01
        • 2013-06-20
        • 2022-12-13
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 2014-02-06
        相关资源
        最近更新 更多