8

ES5 增加了一些方法似乎Object打破了 JavaScript 的语义一致性。

例如,在此扩展之前,JavaScript API 始终围绕对象本身进行操作;

var arrayLength = [].length;
var firstPosInString = "foo".indexOf("o");

...就像新的 Object 方法一样;

var obj = { };
Object.defineProperty(obj, {
    value: 'a',
    writable: false
});

...当以下内容更加符合时:

var obj = { };
obj.defineProperty({
    value: 'a',
    writable: false
});

谁能冷却我的好奇心,为什么会这样?是否有任何代码片段会破坏?标准委员会是否就他们为什么选择这种方法进行了公开讨论?

4

2 回答 2

8

Allen Wirfs-Brock 本人(ES5 规范的编辑,TC39 的成员)在“提议的 ECMAScript 3.1 静态对象函数:用例和基本原理”文档(pdf)中很好地解释了这一切。

我建议阅读所有内容。它非常简短,易于理解,并且很好地展示了这些 ES5 添加背后的思考过程。

但要引用相关部分(强调我的):

在选择提议的 API 之前,考虑了许多替代 API 设计。在考虑替代方案的过程中,我们制定了一套非正式的指导方针,我们在考虑替代方案时应用了这些指导方针。这些指导方针是:

  • 干净地分离元和应用层
  • 尽量减少 API 表面积(即方法的数量及其参数的复杂性)。
  • 专注于命名和参数设计的可用性。
  • 尝试重复应用设计的基本元素。
  • 如果可能,使程序员或实现能够静态优化 API 的使用。

[...]

以下是一些被认为导致所选设计的替代方案。

显而易见的初始想法,遵循已经存在的标准方法 Object.prototype.propertyIsEnumerable 的示例,是在 Object.prototype 上为其他属性和一组并行的属性更改方法添加额外的“propertyIs...”查询方法。

[...]

当我们考虑这种方法时,有很多我们不喜欢的地方,而且似乎与上述 API 设计指南相悖:

  • 合并而不是分离元和应用层。作为 Object.prototype 上的方法,这些方法将成为程序中每个应用程序对象的公共接口的一部分。因此,每个开发人员都需要理解它们,而不仅仅是库设计者。

[...]

于 2012-03-17T00:38:33.737 回答
1

JavaScript API 总是围绕着对对象本身进行操作;

这是不正确的。例如JSONMath总是有自己的方法。没有人会做这样的事情:

var x = 0;
x.cos(); // 1.0
({"a":[0,1],"p":{"x":3,"y":4}}).toJSON();

网上有很多文章说明为什么扩展Object.prototype是一件坏事。是的,它们是关于客户端代码的,但对于某些方面来说,这可能对内置方法也是不利的。

于 2012-03-16T10:12:07.587 回答