Алгоритм проверки равенства массивов в некоторых случаях не работает - PullRequest
3 голосов
/ 12 февраля 2011

У меня есть кусок кода, который проверяет равенство массивов. Он работает как шарм при использовании как:

[1, 2, 3].equals([1, 2, 3]); // true
[1, 2, 3].equals([1, 2, 4]); // false

Приведенный выше результат очевиден и верен, конечно. Тем не менее, следующий случай завершается ошибкой:

[1, 2, undefined].equals([1, 2, undefined]);
// Error:  Cannot read property 'equals' of undefined

Что может быть причиной этого? Я проверяю, есть ли у него свойство, перед тем как его использовать (if (this[i].equals)), так почему он так говорит? Также верно, что undefined === undefined, поэтому я не вижу, в чем проблема.

Функция:

Array.prototype.equals = function(arr) {
    if (this.length !== arr.length) {
        return false;
    }

    for (var i = 0; i < arr.length; i++) {
        if (this[i].equals) {
            if (!this[i].equals(arr[i])) {
                return false;
            } else {
                continue;
            }
        }

        if (this[i] !== arr[i]) {
            return false;
        }
    }

    return true;
}

1 Ответ

2 голосов
/ 12 февраля 2011

Эта строка:

    if (this[i].equals) {

должна быть:

    if (this[i] && this[i].equals) {

, так что если this[i] равно undefined, вы не будете пытаться получить доступ к свойству undefined.


РЕДАКТИРОВАТЬ: Так как вы, кажется, тестируете для массива, будет безопаснее сделать более явный тест, так как любой объект потенциально может иметь .equals property.

Вместо этого вы можете сделать следующее:

if( Object.prototype.toString.call( this[i] ) === '[object Array]' ) {

Это немного длиннее, но точно определит массив, даже если он был создан с помощью ключевого слова new,который отбросит оператор typeof.

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