For..in и hasOwnProperty
Возможный дубликат:
Как проверить, имеет ли объект свойство в Javascript?
Я нашел следующий фрагмент в JT файлах Twitter. Мне было интересно, почему они должны вызвать функцию hasOwnProperty, чтобы увидеть, что "dict" имеет свойство "key"? Цикл for запускается для каждого "ключа" в "dict" , что означает, что "dict" имеет "ключ", не хватает ли точки?
function forEach(dict, f) {
for (key in dict) {
if (dict.hasOwnProperty(key))
f(key, dict[key]);
}
}
Ответы
Ответ 1
Потому что, если вы этого не сделаете, он будет перебирать все свойства в цепочке прототипов, включая те, о которых вы не знаете (которые, возможно, были добавлены кем-то, возиться с прототипами собственных объектов).
Таким образом вам гарантируются только ключи, которые находятся на этом экземпляре объекта.
Ответ 2
Метод hasOwnProperty позволяет узнать, находится ли свойство непосредственно в экземпляре объекта или унаследовано из него прототип цепи.
Рассмотрим следующее
function ObjWithProto() {
this.foo = 'foo_val';
}
ObjWithProto.prototype = {bar: 'bar_val'};
var dict = new ObjWithProto();
dict.foobar = 'foobar_val';
то есть. у вас есть объект dict
со свойствами foo
и foobar
, который также наследует свойство bar
из его прототипа.
Теперь запустите его (измененную версию) вашего кода
function forEach(dict) {
var key;
for (key in dict) {
if ( dict.hasOwnProperty(key) ) console.log('has', key, dict[key]);
else console.log('not', key, dict[key]);
}
}
forEach( dict );
Вы увидите
has foo foo_val
has foobar foobar_val
not bar bar_val
Это позволяет вам отделить свойства, которые есть у объекта, и те, которые он наследует (которые обычно являются методами, не относящимися к циклу)
Кроме того, если вы теперь выполняете dict.bar = 'new_bar_val';
, последний результат изменится на has bar new_bar_val
, позволяя вам различать даже свойства с тем же именем, что и унаследованные.
Ответ 3
Каждый объект в javascript является словарем, это означает, что "toString" и каждый другой метод являются ключом каждого объекта
var myObj = {};
console.log(myObj["toString"]);
Но эта функция наследуется от класса Object, поэтому hasOwnProperty сообщает вам, принадлежит ли этому ключу словарь или если он наследуется.
"toString" in myObj; // true
myObj.hasOwnProperty("toString") // false
Ответ 4
@blockhead прямо здесь. Например, Framework Prototype.js используется для расширения собственных массивов с помощью дополнительных вспомогательных методов (я не знаю ситуации с текущими версиями фреймворка).
Таким образом, прямое использование "for (key in dict)" вернет все элементы div плюс ссылки на вспомогательные методы. Какая неожиданность:)