Цикл JavaScript for in выполняет итерацию по методам?

В статье на yuiblog Дуглас Крокфорд говорит, что Оператор for in будет перебирать методы объекта. Почему следующий код не создает ["a", "b", "c", "d", "toString"]? Разве .toString() и другие методы не являются членами my_obj?

Object.prototype.toString = function(){return 'abc'}
Object.prototype.d = 4;

my_obj = {
    'a':1,
    'b':2,
    'c':3
}

a = []
for (var key in my_obj) {
    a.push(key)
}

console.log(a) // prints ["a", "b", "c", "d"]

person hekevintran    schedule 30.03.2010    source источник


Ответы (2)


Все определяемые пользователем свойства являются перечисляемыми, включая свойства, унаследованные от прототипа. Встроенные нативные свойства — нет. toString() является одним из них. См. здесь https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Statements/For...in

Изменить. Моя интерпретация "Однако цикл будет перебирать все пользовательские свойства (включая те, которые перезаписывают встроенные свойства)" заключается в том, что перезаписываемые свойства непосредственно в объекте становятся перечисляемыми. Не перезапись в самом прототипе. Это означает:

var my_obj = {a: 1, b: 2, c: 3};
my_obj.toString = function() {return 'abc';};

a = []
for (var key in my_obj) {
    a.push(key)
}

console.log(a) // prints ["a", "b", "c", "toString"]
person Chetan S    schedule 30.03.2010
comment
Ага, Object.prototype.toString.propertyIsEnumerable() == false - person Christian C. Salvadó; 30.03.2010
comment
Из документа, на который вы ссылаетесь: цикл for...in не перебирает встроенные свойства. К ним относятся все встроенные методы объектов, такие как метод indexOf String или метод toString объекта. Однако цикл будет перебирать все пользовательские свойства (включая те, которые перезаписывают встроенные свойства). Почему в документе говорится, что включая любые перезаписывающие встроенные свойства, если в моем примере .toString() не перезаписывается? - person hekevintran; 30.03.2010
comment
@hekevintran: обновил мой ответ. - person Chetan S; 30.03.2010
comment
Я понимаю. Благодарю за разъяснение. - person hekevintran; 30.03.2010

for..in перебирает пользовательские свойства. Если вы измените свой код на:

Object.prototype.foo = function() { return 'abc'; };

затем

console.log(a);

Выведет:

["a", "b", "c", "foo", "d"]

Как указал Четан Шастри, toString обрабатывается по-разному, поскольку это встроенное собственное свойство.

person Justin Johnson    schedule 30.03.2010