ES5中的Object.defineProperty?

我看到有关“新”Object.create,使枚举可configuration的post。 但是,它依赖于Object.defineProperty方法。 我找不到这个方法的跨浏览器实现。

我们坚持写旧的Object.create吗? 我不能写在IE6 / 7中不起作用的东西。

在ECMAScript 3环境中,您无法从ECMAScript 5 Object.create方法中模拟出几件事情。

正如你所看到的,properties参数会给你带来问题,因为在基于E3的实现中, 没有办法改变属性的属性。

作为@Raynos提到的Object.defineProperty方法,在IE8上工作,但部分地 ,它只能在DOM元素中使用。

accessor属性也会给你带来问题,可以用广泛支持的非标准方法来模仿 ,比如__defineGetter__ / __defineSetter__ ,但是你不能改变属性的属性

抛开属性描述符的另一个问题是, Object.create方法可以接受null作为参数,以创build一个不从任何东西inheritance的对象。

这不能用Crockford的Object.create shim来模拟,因为当new操作符与具有包含nullprototype属性(或任何其他非对象值)的构造函数一起使用时,新创build的对象将从Object.prototypeinheritanceObject.prototype默认情况下。

在一些实现-V8,Spidermonkey,Rhino等中,他们有一个可设置的__proto__属性,可以用来设置一个null [[Prototype]],但是这又是非标准的,肯定它永远不会工作在IE上。

我会build议,如果你想针对旧的浏览器不使用这些function,因为没有办法让他们在这些环境中正常工作。

如果你仍然想使用Object.create ,而不使用属性参数,你可以,但是我build议你检测不能模拟的东西。

以下将是一个更安全的Crockford的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-shim

不幸的是,你不能在ES3环境中configuration枚举。 这个垫片可以让你在任何环境下调用API,但是这些属性在ES3下仍然可以被枚举。

物有所值,

Object.defineProperty在ie8和FF4中工作。

这意味着它的function嗅探和实施它有用的地方,因为你希望从6/7到8/9的升级将在未来几年发生。

另一个值得警惕的是dontEnum属性在JScript中有一个bug

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

[编辑]:

这是Internet Explorer的文档和ES5规范的链接(页122,15.2.3.6)