ECMAScript 5 有很多不错的新增功能。 John Resig has a good overview here .这里有个好ECMAScript 5 compatibility table .
对于尚不支持这些功能的浏览器,很多这些东西都可以“伪造”。您知道可以执行此操作的任何脚本吗?我对 Object.create 特别感兴趣。
例如,Douglas Crockford's JSON script在创建 JSON 函数之前检查它们是否存在。
如果有更多类似 JSON 的内容,我们可以在需要使用新函数时包含它们。
最佳答案
Crockford recommends这种 Object.create
垫片:
if (typeof Object.create != "function") {
Object.create = function (o) {
function F(){}
F.prototype = o;
return new F;
};
}
但是请不要这样做。
这种方法的问题是 ES5 Object.create
有一个2 个参数 的签名:第一个 — 一个要继承的对象,第二个(可选)—表示要添加到新创建的对象的属性(或者更确切地说,描述符)的对象。
Object.create(O[, Properties]); // see 15.2.3.5, ECMA-262 5th ed.
我们所拥有的是具有 2 种不同行为的不一致实现。在具有原生 Object.create
的环境中,方法知道如何处理第二个参数;在没有原生 Object.create
的环境中,它不会。
有什么实际意义?
好吧,如果有一些代码(比如第三方脚本)想要使用 Object.create
,那么该代码执行此操作是相当合理的:
if (Object.create) {
var child = Object.create(parent, properties);
}
——本质上假设如果 Object.create
存在,它必须符合规范——接受第二个参数并将相应的属性添加到对象。
但是,对于上述垫片,第二个参数被简单地忽略了。甚至没有迹象表明有什么不同的错误。无声的故障,可以这么说——检测和修复起来相当痛苦。
我们可以做得更好吗?
好吧,实际上不可能仅使用(标准)ES3 设施创建一个完全符合的 Object.create
shim。最好的解决方案是创建自定义包装器方法。
但是,您可以尝试的替代方案(不太理想)很少:
1) 通知用户无法使用第二个参数
if (!Object.create) {
Object.create = function (o) {
if (arguments.length > 1) {
throw Error('second argument is not supported');
}
// ... proceed ...
};
}
2) 尝试处理第二个参数:
if (!Object.create) {
Object.create = function (parent, properties) {
function F(){}
F.prototype = parent;
var obj = new F;
if (properties) {
// ... augment obj ...
}
return obj;
};
}
请注意,“properties”是一个表示属性描述符的对象,而不仅仅是属性名称/值,而且支持起来不是很简单(有些事情甚至是不可能的,例如控制可枚举性属性):
Object.create(parent, {
foo: {
value: 'bar',
writable: true
},
baz: {
get: function(){ return 'baz getter'; },
set: function(value){ return 'baz setter'; },
enumerable: true
}
});
原始 shim 中的另一个不一致之处是它没有处理 parent object being null
。
var foo = Object.create(null);
这将创建一个对象,其 [[Prototype]] 为 null
;换句话说,对象不继承任何东西,甚至 Object.prototype
(ECMAScript 中的所有原生对象都继承自它)。
foo.toString; // undefined
foo.constructor; // undefined
// etc.
顺便说一句,这对于在 ECMAScript 中创建“适当的”哈希表很有用。
可以模拟这种行为,但只能使用非标准扩展,例如“神奇的”__proto__
属性(因此实现不是很便携或健壮)。这个问题的解决方案是相似的:要么完全模拟 ES5 实现,要么通知不一致/失败。
关于javascript - 新的 ECMAScript 5 函数有哪些现代化脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3075308/