1

I know you should avoid it, thus although annoying I always protect myself against it.

But what exactly causes extensions to a prototype to show up when using "for in"? Sometimes it is (or seems to be) safe to use "for in" and other times it isn't.

i.e.:

I'm talking about for example:

Array.prototype.last = function(){ return this[this.length-1]; }

Showing up as:

for(var k in someArray){
    console.log("%o %o", k, someArray[k]); // eventually outputs "last 'function(){ return this[this.length-1]; }'
}
4

2 に答える 2

4

This behavior is by design.

for in loops over all enumerable properties, including those inherited from the prototype.

于 2013-01-23T14:12:24.737 に答える
3

SLaksが言ったように、それは仕様によるものです。プロパティ(継承されているかどうか)がfor..inループに表示されるかどうかを決定するのは、その[[Enumerable]]内部属性です。trueの場合、プロパティは表示されます。それ以外の場合は表示されません。

すべてのプロパティにはそのような属性があります(そして他のいくつかのプロパティ)。を使用して確認できますObject.getOwnPropertyDescriptor。たとえば、あなたのArray.prototype.last方法を考えてみましょう:

var descriptor = Object.getOwnPropertyDescriptor(Array.prototype, "last");

次のようなオブジェクトが返されます。

{
configurable: true,
enumerable: true,
value: function (){ return this[this.length-1]; },
writable: true
}

[[Enumerable]]の値を変更して、ループObject.definePropertyから隠すことができます。for..in

descriptor.enumerable = false;
Object.defineProperty(Array.prototype, "last", descriptor);
于 2013-01-23T14:18:17.980 に答える