javascript - 新的 ECMAScript 5 函数有哪些现代化脚本?

标签 javascript cross-browser backwards-compatibility ecmascript-5

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/

相关文章:

javascript - 我通过 JQuery AJAX 请求收到的数据有什么问题?

javascript - 从JavaScript获取手机的唯一ID

css - Android 2.3.3 浏览器中的字体图标为正方形

ios6 - 如何让应用兼容 iOS 6 和 iOS 7?

python - 如何查看代码是否向后兼容 Python?

android - 向后兼容性和 Android Open Accessory 库

javascript - mootools 菜单 document.id 到 document.getElements

Javascript。比较 UNIX 时间戳

javascript - 如何使 event.srcElement 在 Firefox 中工作,它是什么意思?

javascript - 为什么会出现资源加载失败的情况?