для (var i в aArray) VS для (i = 0; i - PullRequest
1 голос
/ 01 апреля 2011

Я просто хочу спросить, совпадают ли in_array_orig и in_array_new а также я запутался в результате при сравнении обоих массивов ( aArr1 против aArr2 ).

Может кто-нибудь объяснить мне. спасибо

Вот мой пример кода теста

function echo(s)
{
    document.write(s);
}

function in_array_orig(oItem, aArray)
{   
    for (var i=0; i<aArray.length; i++) if (aArray[i] == oItem) return true;

    return false;
}

function in_array_new(oItem, aArray)
{
    for (var i in aArray) if (aArray[i] == oItem) return true;

    return false;
}

var a = ['gab', '24', 'manila'];

var aArr1 = [1];
var b = {0:aArr1, 1:24, 2:'manila'};

var aArr2 = [1];


echo(in_array_orig(24, a)); // true
echo(in_array_new(24, b)); // true

echo(in_array_orig(aArr2, b)); // false
echo(in_array_new(aArr2, b)); // false

echo ((aArr1==aArr2)); // false
echo ((aArr1===aArr2)); // false

спасибо заранее

Ответы [ 6 ]

6 голосов
/ 01 апреля 2011

Оператор in возвращает true, если свойство находится в объекте. Это включает в себя поиск по всей цепочке прототипов. Например:

Object.prototype.k = 5;
f = {};
'k' in f; // true

Несмотря на то, что f является пустым объектом, его прототип (как и все типы в JS) включает в себя объект Object, который имеет свойство 'k'.

Хотя вы и не спрашивали, полезная функция для проверки только собственных свойств объекта - .hasOwnProperty(), поэтому в нашем примере выше:

f.hasOwnProperty('k'); // false, that's more what we would expect

Хотя для массивов вы (обычно) не хотите итерировать по всем свойствам, поскольку эти свойства могут включать в себя иные вещи, кроме значений индекса, поэтому как по соображениям производительности, так и по ожидаемому поведению следует использовать обычный for(var i=0;i<n;i++).

Таким образом, если вы используете массивы, перейдите с in_array_orig, а для объектов, для которых вас интересуют их свойства, используйте in_array_new (который должен быть соответствующим образом переименован, in_obj или что-то в этом роде).

Кроме того, [1] == [1] возвращает false, поскольку два объекта / массива не являются одинаковыми объектами. Действительно, каждое из их свойств и индексов имеет одинаковое значение, хотя они не находятся в одном и том же месте в памяти и, следовательно, не считаются равными. Вы можете легко построить ( или найти в сети ) процедуру глубокого поиска equals(), чтобы проверить, действительно ли два объекта / массива равны по значению (в отличие от адреса).

0 голосов
/ 01 апреля 2011

К первому вопросу обращайтесь http://www.openjs.com/articles/for_loop.php

О втором:

echo(in_array_orig(24, a)); // true
echo(in_array_new(24, b)); // true

Я думаю, это не будет проблемой для вас.

echo(in_array_orig(aArr2, b));
echo(in_array_new(aArr2, b));

Обе они определенно были бы ложными, потому что они не где-то внутри b. Если вы сделаете небольшое изменение в b:

var b = {0:aArr1, 1:24, 2:'manila', 3:[1]};

тогда попробуйте это:

console.log(in_array_new(aArr2, b[3]));
console.log(in_array_orig(aArr2, b[3]));

они оба Верно сейчас.

Наконец, последнее:

echo ((aArr1==aArr2));

Оператор "==" сравнивает их значение, так что это неверно, поскольку они явно несут различное содержимое, то есть значение.

echo ((aArr1===aArr2));

"===" сравнивает их значение и тип, их значения различны, но их типы совпадают, вы можете проверить это:

console.log(typeof aArr1===typeof aArr2);

таким образом, это все еще Ложь .

0 голосов
/ 01 апреля 2011

Да, между ними есть различия.

Во-первых, синтаксис for(var i=0; i<aArray.length; i++), очевидно, будет корректно работать только для массивов, которые имеют только числовые ключи, и в которых нет последовательности в последовательности клавиш. Если это не относится к вашим данным, то этот синтаксис, очевидно, создаст вам проблемы.

Но настоящие различия сводятся к тому, как Javascript обрабатывает массивы и объекты.

Использование for(x in y) заставляет JS перебирать все свойства и методы в объекте .

В JS массив - это просто тип объекта с несколькими предопределенными методами и свойствами, такими как length, чтобы найти количество элементов массива, pop() и push() для добавления и удаления элементов и т. Д.

Если вы используете синтаксис for(x in y) в массиве , он будет включать некоторые из этих методов и свойств в цикл. Это вряд ли то, что вы хотели, и может вызвать некоторые странные побочные эффекты.

Поэтому, если вы хотите использовать for(x in y), лучше начинать с объекта , а не с массива .

Надеюсь, это поможет.

0 голосов
/ 01 апреля 2011

in_array_orig будет работать только с массивами, in_array_new также будет работать со словарями.Для массивов их результаты будут такими же, но нет гарантии, что элементы будут обработаны в правильном порядке в in_array_new (в случае этой функции это не имеет значения).

О сравнении массивов этоКажется, что JavaScript не сравнивает массивы поэлементно, а скорее сравнивает, если массив является тем же объектом в памяти, например:

aArr1 == aArr1 // true
0 голосов
/ 01 апреля 2011

, если in_array_orig и in_array_new - это то же самое

Да, они есть.(то же поведение)

я запутался в результате при сравнении обоих массивов (aArr1 против aArr2)

Мы не можем сравнить массив следующим образом: aArr1 == aArr2

0 голосов
/ 01 апреля 2011

Полагаю, это уже обсуждалось здесь в SO.

См. Здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...