我正在看到有关“新”Object.create的帖子,它使枚举可配置。但是,它依赖于Object.defineProperty方法。我找不到这种方法的跨浏览器实现。
我们是否坚持为旧的Object.create写作?我不能写一些在IE6 / 7中无效的东西。
答案 0 :(得分:14)
在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
[[原型]],但同样,这是非标准,并且肯定它永远不会在IE上运行。
我建议,如果您希望将旧浏览器作为目标,请不要使用这些功能,因为无法让它们在这些环境中正常运行。
如果您仍想使用Object.create
,而不使用属性参数,则可以,但我建议您检测无法模拟的内容。
以下是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;
};
})();
}
无论如何,请小心使用。
答案 1 :(得分:4)
如果您想要一个好的defineProperty()实现,请查看https://github.com/kriskowal/es5-shim
不幸的是,您无法在ES3环境中配置枚举。此填充程序将允许您在任一环境中调用API,但在ES3下仍可以枚举属性。
答案 2 :(得分:2)
为了它的价值,
Object.defineProperty适用于ie8和FF4。
这意味着它值得嗅探并在有用的地方实施它,因为您希望在未来几年内从6/7升级到8/9。
另一件需要注意的事情是dontEnum属性在JScript中有一个错误
您必须解决在IE中使用dontEnum属性的方式。
[编辑]:
以下是Internet explorer的文档和ES5 specification的链接(第122页,15.2.3.6)