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

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

有帮助吗?

解决方案

有几件事是您无法从 ECMAScript 5 中模拟的 Object.create ECMAScript 3 环境上的方法。

正如您所看到的,属性参数会给您带来问题,因为在基于 E3 的实现中存在 决不 更改属性属性。

Object.defineProperty 方法如 @Raynos 提到过,可以在 IE8 上运行,但是 部分地, ,可以使用 仅有的 在 DOM 元素中。

访问器属性 会给你带来问题,它们可能是 模仿的 具有广泛支持的非标准方法,例如 __defineGetter__/__defineSetter__, ,但是你再说一次 无法更改属性属性.

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

这不能用以下方法模拟 克罗克福德的 Object.create 垫片, ,因为当 new 运算符与构造函数一起使用,该构造函数具有 prototype 属性包含 null -或任何其他非对象值-,新创建的对象将继承自 Object.prototype 无论如何默认。

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

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

如果您还想使用 Object.create, ,不使用 特性 争论,你可以,但是我建议你检测那些无法模仿的东西。

以下将是一个 更安全 的版本 克罗克福德的 Object.create 垫片:

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;
    };
  })();
}

无论如何,请谨慎使用。

其他提示

如果你想有一个良好的defineProperty()实现,看看 https://github.com/ kriskowal / ES5-垫片

不幸的是,你不能枚举配置在ES3环境。该垫片将让你在打电话或者环境的API,但性能仍然会ES3下枚举。

有关它的价值,

Object.defineProperty 工作在IE8和FF4。

这意味着它值得有嗅和实现它的地方是,你会希望从即升级6/7到8/9将发生在未来几年很有用眼看。

警惕的另一件事是,dontEnum属性在的JScript 一个错误

您必须解决您使用IE中dontEnum财产的方式。

[编辑]:

下面是 Internet Explorer的和文档一个链接到 ES5规范(页122 ,15.2.3.6)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top