11

我经常使用以下方法获取对象键数组:

Object.keys(someobject)

我很乐意这样做。我知道 Object 是 Object 构造函数,而 keys() 是它的一种方法,并且 keys() 将返回作为第一个参数给出的任何对象的键列表。我的问题不是如何获取对象的密钥- 请不要回复解释此问题的非答案。

我的问题是,为什么 Object.prototype 上没有更可预测的 keys() 或 getKeys() 方法或 keys 实例变量,所以我可以拥有:

someobject.keys()

或作为实例变量:

someobject.keys

并返回键数组?

同样,我的目的是了解 Javascript 的设计,以及获取密钥的有点不直观的机制的目的是什么。我不需要帮助来获取钥匙。

4

3 回答 3

16

我想他们不希望有太多属性,Object.prototype因为您自己的属性可能会影响它们。

它们包含的越多,发生冲突的机会就越大。


如果keysprototype...

var myObj: {
   keys: ["j498fhfhdl89", "1084jnmzbhgi84", "jf03jbbop021gd"]
};

var keys = Object.prototype.keys.call(myObj);

引入潜在阴影属性如何破坏代码的示例。

对于为什么向Object.prototype.

想象一些看起来像这样的代码并不难......

if (someObject.keys) {
    someObject.keys.push("new value")
else
    someObject.keys = ["initial value"]

显然,如果您将keys函数添加到Object.prototype. 现在将成为阴影属性的事实someObject.keys破坏了编写为假定它不是阴影属性的代码。


后见之明是 20/20

如果您想知道为什么keys它不是原始语言的一部分,那么人们至少会习惯于围绕它进行编码......好吧,我猜他们认为没有必要,或者根本没有想到它。

语言中不包含许多可能的方法和语法特性。这就是我们对规范进行修订以添加新功能的原因。例如,Array.prototype.forEach是后期添加。但他们可以将它添加到Array.prototype,因为它不会破坏Array.

一种语言应该在其1.0发行版中包含所有可能的功能并不是一个现实的期望。

由于Object.keys只是返回一个对象的可枚举自身属性的数组,因此这是一个非必要的添加,可以通过现有的语言特性来实现。它没有更早出现也就不足为奇了。


结论

添加keysObject.prototype大多数肯定破坏遗留代码。

在像 JavaScript 这样非常流行的语言中,向后兼容性肯定是一个重要的考虑因素。在这一点上添加新属性Object.prototype可能是灾难性的。

于 2012-08-12T13:44:39.030 回答
7

我想您的问题的答案是“因为委员会如此决定”,但我已经听到您问“为什么?” 在这句话结束之前。

我最近读到了这个,但我现在找不到来源。归结为,在许多情况下,您Object.prototype.keys.call(myobject)无论如何都必须使用,因为可能myobject.keys已经在对象中用于其他用途。

我想你会发现这个归档邮件线程很有趣,例如Brendan Eich讨论了 ECMAScript 5 中新方法的某些方面。

更新: 在挖掘邮件档案时,我发现了这个

主题:是否应该将 Object.keys 重新定位为 Object.prototype.keys

讨论:Allen 认为这并不是真正的元层操作,因为它旨在用于应用程序层代码,作为 for..in 的替代方案,用于获取可枚举属性名称的列表。作为应用层方法,它属于 Object.prototype 而不是 Object 构造函数。原则上达成了普遍共识,但 Doug 和 Mark 务实地争辩说,用户定义的对象很可能会定义自己的名为“keys”的属性,这会影响 Object.prototype.keys 使其无法用于此类对象。

行动:将其保留为 Object.keys。

于 2012-08-12T16:28:01.770 回答
4

随意制作自己的,但添加到Object原型中的属性越多,碰撞的机会就越高。这些冲突很可能会破坏任何第三方 javascript 库以及任何依赖for...in循环的代码。

Object.prototype.keys = function () {
    return Object.keys(this);
};

for (var key in {}) {
    // now i'm getting 'keys' in here, wtf?
}

var something = {
    keys: 'foo'
};

something.keys(); // error
于 2012-08-12T13:48:07.400 回答