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
操作符与具有包含null
的prototype
属性(或任何其他非对象值)的构造函数一起使用时,新创build的对象将从Object.prototype
inheritanceObject.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)