11

私は頻繁に以下を使用してオブジェクトキーの配列を取得します:

Object.keys(someobject)

私はこれを快適に行うことができます。ObjectはObjectコンストラクター関数であり、keys()はそのメソッドであり、keys()は、最初のパラメーターとして指定されたオブジェクトのキーのリストを返すことを理解しています。私の質問は、オブジェクトのキーを取得する方法ではありません。これを説明する非回答で返信しないでください。

私の質問は、なぜもっと予測可能なkeys()またはgetKeys()メソッド、あるいはObject.prototypeで利用可能なkeysインスタンス変数がないので、次のことができるのかということです。

someobject.keys()

またはインスタンス変数として:

someobject.keys

そして、キーの配列を返しますか?

繰り返しになりますが、私の意図は、Javascriptの設計と、キーをフェッチするというやや直感的でないメカニズムがどのような目的に役立つのかを理解することです。キーを取得するのに助けは必要ありません。

4

3 に答える 3

16

Object.prototypeあなた自身のプロパティがそれらをシャドウする可能性があるので、彼らはあまり多くのプロパティを望んでいないと思います。

それらが含まれるほど、競合の可能性が高くなります。


keysにあった場合、このオブジェクトのキーを取得するのは非常に不器用ですprototype...

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"]

Clearly this code would break if you add a keys function to Object.prototype. The fact that someObject.keys would now be a shadowing property breaks the code that is written to assume that it is not a shadowing property.


Hindsight is 20/20

If you're wondering why keys wasn't part of the original language, so that people would at least be accustomed to coding around it... well I guess they didn't find it necessary, or simply didn't think of it.

There are many possible methods and syntax features that aren't included in the language. That's why we have revisions to the specification, in order to add new features. For example, Array.prototype.forEach is a late addition. But they could add it to Array.prototype, because it doesn't break proper uses of Array.

It's not a realistic expectation that a language should include every possible feature in its 1.0 release.

Since Object.keys does nothing more than return an Array of an Object's enumerable own properties, it's a non-essential addition, that could be achieved with existing language features. It should be no surprise that it wasn't present earlier.


Conclusion

Adding keys to Object.prototype most certainly would break legacy code.

In a tremendously popular language like JavaScript, backward compatibility is most certainly going to be an important consideration. Adding new properties to Object.prototype at this point could prove to be disastrous.

于 2012-08-12T13:44:39.030 に答える
7

I guess an answer to your question is "Because the committee decided so", but I can already hear you ask "why?" before the end of this sentence.

I read about this recently but I can't find the source right now. What it boiled down to was that in many cases you had to use Object.prototype.keys.call(myobject) anyway, because the likelihood of myobject.keys already being used in the object for something else.

I think you will find this archived mail thread interesting, where for example Brendan Eich discuss some aspects of the new methods in ECMAScript 5.

Update: While digging in the mail-archive I found this:

Topic: Should Object.keys be repositioned as Object.prototype.keys

Discussion: Allen argued that this isn't really a meta layer operation as it is intended for use in application layer code as an alternative to for..in for getting a list of enumerable property names. As a application layer method it belongs on Object.prototype rather than on the Object constructor. There was general agreement in principle, but it was pragmatically argued by Doug and Mark that it is too likely that a user defined object would define its own property named "keys" which would shadow Object.prototype.keys making it inaccessible for use on such objects.

Action: Leave it as Object.keys.

于 2012-08-12T16:28:01.770 に答える
4

Feel free to make your own, but the more properties you add to the Object prototype, the higher chance you'll collide. These collisions will most likely break any third party javascript library, and any code that relies on a for...in loop.

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 に答える