Javascript:为什么是Object.keys(someobject),而不是someobject.keys?

mik*_*ana 9 javascript arrays oop language-design javascript-objects

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

Object.keys(someobject)
Run Code Online (Sandbox Code Playgroud)

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

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

someobject.keys()
Run Code Online (Sandbox Code Playgroud)

或作为实例变量:

someobject.keys
Run Code Online (Sandbox Code Playgroud)

并返回键数组?

同样,我的目的是理解Javascript的设计,以及获取密钥的有点不直观的机制服务的目的是什么.获取密钥我不需要帮助.

小智 13

我想他们不需要太多属性,Object.prototype因为你自己的属性可以遮蔽它们.

它们越多,冲突的可能性就越大.


如果keysprototype... 上获取此对象的密钥将是非常笨拙的...

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

var keys = Object.prototype.keys.call(myObj);
Run Code Online (Sandbox Code Playgroud)

引入潜在阴影属性的示例可能会破坏代码.

似乎有一些混淆,为什么添加新属性是一个大问题Object.prototype.

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

if (someObject.keys) {
    someObject.keys.push("new value")
else
    someObject.keys = ["initial value"]
Run Code Online (Sandbox Code Playgroud)

显然,如果你添加一个keys函数,这段代码就会破坏Object.prototype.someObject.keys现在将成为阴影属性的事实会破坏编写的代码,假设它不是阴影属性.


后见之明是20/20

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

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

语言应该包含其1.0发布中的所有可能功能,这并不是一个现实的期望.

因为Object.keys只返回一个Object的可枚举自身属性的数组,它是一个非必要的补充,可以通过现有的语言功能实现.它早先不存在应该不足为奇.


结论

添加keysObject.prototype肯定打破旧的代码.

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

  • +1.是的,我想有很多JS代码与你的例子中的对象相似.如果语言中的新功能强制更改遗留代码,那将会非常烦人. (2认同)

som*_*ome 6

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

我最近读到了这个,但我现在找不到来源.它归结为在许多情况下你必须使用Object.prototype.keys.call(myobject),因为myobject.keys已经在对象中使用其他东西的可能性.

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

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

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

讨论:Allen认为这不是一个真正的元层操作,因为它旨在用于应用程序层代码,作为获取可枚举属性名称列表的替代方法.作为应用层方法,它属于Object.prototype而不是Object构造函数.原则上普遍认同,但道格和马克务实地认为,用户定义的对象很可能会定义自己的名为"keys"的属性,这会影响Object.prototype.keys,使其无法在此类上使用.对象.

操作:将其保留为Object.keys.