Ответ 1
Вы можете использовать JavaScript hasOwnProperty для достижения этого в цикле, например:
for(var key in arr) {
if (arr.hasOwnProperty(key)) {
...
}
}
Ссылка: Эта статья блога YUI.
Итак, скажем, я добавил некоторые методы прототипа в класс Array:
Array.prototype.containsKey = function(obj) {
for(var key in this)
if (key == obj) return true;
return false;
}
Array.prototype.containsValue = function(obj) {
for(var key in this)
if (this[key] == obj) return true;
return false;
}
то я создаю ассоциативный массив и пытаюсь пропустить его через клавиши:
var arr = new Array();
arr['One'] = 1;
arr['Two'] = 2;
arr['Three'] = 3;
for(var key in arr)
alert(key);
это возвращает пять элементов:
-One -Two -Three -containsKey -containsValue
но я хочу (ожидать?) только три. Я подхожу к этому неправильно? есть ли способ "скрыть" прототипы? или я должен делать что-то по-другому?
Вы можете использовать JavaScript hasOwnProperty для достижения этого в цикле, например:
for(var key in arr) {
if (arr.hasOwnProperty(key)) {
...
}
}
Ссылка: Эта статья блога YUI.
Вы можете добиться желаемого результата с другого конца, сделав методы прототипа неперечислимыми:
Object.defineProperty(Array.prototype, "containsKey", {
enumerable: false,
value: function(obj) {
for(var key in this)
if (key == obj) return true;
return false;
}
});
Это обычно работает лучше, если у вас есть контроль над определениями методов, и, в частности, если у вас нет контроля над тем, как ваш код будет вызываться другими людьми, что является общим предположением в разработке кода библиотеки.
Javascript не поддерживает ассоциативные массивы так, как вы думаете. http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful
for (var я in.. получает все свойства объекта (массив - это еще один объект), поэтому вы видите другие объекты, которые вы прототипировали.
Как говорится в статье, вы должны использовать объект:
var assoc = {'One' : 1, 'Two' : 2};
assoc['Three'] = 3;
for(var key in assoc)
alert(key+' => '+assoc[key]);
вы можете сделать это:
for(var key in arr)
{
if (typeof(arr[key]) == "function")
continue;
alert(key);
}
Но это дрянное обходное решение
Для высокопроизводительной итерации по массивам JavaScript используйте либо цикл for
, либо while
. Николас Закас обсуждает наиболее эффективные варианты повторения массивов в своем Tech Talk Ускорить свой JavaScript.
Лучше всего, наверное, что-то вроде этого:
for (var i = collection.length - 1; i >= 0; i--) {
if (obj == collection[i]) return true;
}
Этот подход будет лучше всего по нескольким причинам:
length
доступно только один раз, при инициализации циклаi >= 0
) вместо другой переменной