Вот моя попытка выполнить ваш запрос на тот случай, если вы искали альтернативы. Этот метод просто обрабатывает ошибки как допустимые результаты и кодируется аналогично

var a = [1, 2, 3];
var b = [3, 2, 1];
var c = new Array(1, 2, 3);

alert(a == b   "|"   b == c);

на Jake Archibald на HTML5 Rocks.

, если они равны? true Предлагает ли jQuery какой-либо метод для этого?

помечены

user633183 , таких как Пользователи с вопросами Javascript javascript Javascript можно в одиночку закрыть 23 августа ’16 в 3:06 Этот вопрос уже задавался ранее и уже имеет ответ. Если эти ответы не полностью отвечают на ваш вопрос, пожалуйста,

задайте новый вопрос Вариант 1 Глядя на вывод

Original Gist: stringifyни < > Глядя на вывод

function arraysEqual(a, b) {
  if (a === b) return true;
  if (a == null || b == null) return false;
  if (a.length != b.length) return false;

  // If you don't care about the order of the elements inside
  // the array, you should sort both arrays here.
  // Please note that calling sort on an array will modify that array.
  // you might want to clone your array first.

  for (var i = 0; i < a.length;   i) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

Самый простой вариант, работает почти во всех случаях, за исключением того, что

! == null, но они оба преобразован в представление JSON undefined и считается равным: null Это может не сработать, если ваш массив содержит объекты.

function arraysEqual(a1,a2) {
    /* WARNING: arrays must not contain {objects} or behavior may be undefined */
    return JSON.stringify(a1)==JSON.stringify(a2);
}

Обратите внимание, что для тех, кто использует новый Работает ли это с объектами, зависит от того, сортирует ли реализация JSON ключи. Например, JSON для может быть равен или не равен {1:2,3:4}. Если вы решите не использовать объекты в своих списках, это должно работать нормально. Если у вас есть объекты в вашем списке, которые имеют уникальный идентификатор, вы можете сделать {3:4,1:2} [ОБНОВЛЕНИЕ] По крайней мере в Chrome, функция JSON.stringify имеет тенденцию возвращать ключи в том порядке, в котором они были определены (по крайней мере, я это заметил), но это поведение очень подвержено изменениям в любой момент и должно не полагаться. . Если в вашем списке есть произвольные объекты, вы можете прочитать опцию # 2.) a1.map(function(x)}{return {id:x.uniqueId}}) Это также работает для вложенных массивов.

Это, однако, немного неэффективно из-за накладных расходов, связанных с созданием этих строк и сборкой мусора.

Вариант 2


Вариант 2

Более «правильная» опция, которую вы можете переопределить для работы с особыми случаями (например, обычными объектами и нулевыми / неопределенными и пользовательскими объектами, если вы того пожелаете):

// generally useful functions
function type(x) { // does not work in general, but works on JSONable objects we care about... modify as you see fit
    // e.g.  type(/asdf/g) --> "[object RegExp]"
    return Object.prototype.toString.call(x);
}
function zip(arrays) {
    // e.g. zip([[1,2,3],[4,5,6]]) --> [[1,4],[2,5],[3,6]]
    return arrays[0].map(function(_,i){
        return arrays.map(function(array){return array[i]})
    });
}
// helper functions
function allCompareEqual(array) {
    // e.g.  allCompareEqual([2,2,2,2]) --> true
    // does not work with nested arrays or objects
    return array.every(function(x){return x==array[0]});
}

function isArray(x){ return type(x)==type([]) }
function getLength(x){ return x.length }
function allTrue(array){ return array.reduce(function(a,b){return a&&b},true) }
    // e.g. allTrue([true,true,true,true]) --> true
    // or just array.every(function(x){return x});
function allDeepEqual(things) {
    // works with nested arrays
    if( things.every(isArray) )
        return allCompareEqual(things.map(getLength))     // all arrays of same length
               && allTrue(zip(things).map(allDeepEqual)); // elements recursively equal

    //else if( this.every(isObject) )
    //  return {all have exactly same keys, and for 
    //          each key k, allDeepEqual([o1[k],o2[k],...])}
    //  e.g. ... && allTrue(objectZip(objects).map(allDeepEqual)) 

    //else if( ... )
    //  extend some more

    else
        return allCompareEqual(things);
}

Но когда мы говорим о адаптивных экранах и если по какой-то причине мы хотим обрабатывать их с помощью jQuery,

allDeepEqual([ [], [], [] ])
true
allDeepEqual([ [1], [1], [1] ])
true
allDeepEqual([ [1,2], [1,2] ])
true
allDeepEqual([ [[1,2],[3]], [[1,2],[3]] ])
true

allDeepEqual([ [1,2,3], [1,2,3,4] ])
false
allDeepEqual([ [[1,2],[3]], [[1,2],[],3] ])
false
allDeepEqual([ [[1,2],[3]], [[1],[2,3]] ])
false
allDeepEqual([ [[1,2],3], [1,[2,3]] ])
false

Чтобы использовать это как обычную функцию, выполните:

function allDeepEqual2() {
    return allDeepEqual([].slice.call(arguments));
}

Но когда мы говорим о адаптивных экранах и если по какой-то причине мы хотим обрабатывать их с помощью jQuery,

allDeepEqual2([[1,2],3], [[1,2],3])
true

Варианты 3

I Вместо этого используйте любой из методов, ранее упомянутых другими: свойство : это 2016 год, и мой предыдущий слишком сложный ответ меня беспокоил. Эта рекурсивная, императивная реализация «рекурсивного программирования 101» делает код действительно простым и, более того, дает сбой в самом раннем случае (что дает нам эффективность). Он также не генерирует лишние эфемерные структуры данных (не то, что в функциональном программировании вообще что-то не так, а просто поддержание его в чистоте).

Если бы мы хотели применить это к непустым массивам массивов, мы могли бы сделать seriesOfArrays.reduce (arraysEqual).

Это его собственная функция, в отличие от использования Object.defineProperties для присоединения к Array.prototype, поскольку это приведет к ошибке с ключевой ошибкой, если мы передадим неопределенное значение (однако это хорошее решение для проектирования, если вы хотите Сделай так).

Это только ответ на оригинальный вопрос ОП.

function arraysEqual(a,b) {
    /*
        Array-aware equality checker:
        Returns whether arguments a and b are == to each other;
        however if they are equal-lengthed arrays, returns whether their 
        elements are pairwise == to each other recursively under this
        definition.
    */
    if (a instanceof Array && b instanceof Array) {
        if (a.length!=b.length)  // assert same length
            return false;
        for(var i=0; i<a.length; i  )  // assert each element equal
            if (!arraysEqual(a[i],b[i]))
                return false;
        return true;
    } else {
        return a==b;  // if not both arrays, should be the same
    }
}

Примеры:

arraysEqual([[1,2],3], [[1,2],3])
true
arraysEqual([1,2,3], [1,2,3,4])
false
arraysEqual([[1,2],[3]], [[1,2],[],3])
false
arraysEqual([[1,2],[3]], [[1],[2,3]])
false
arraysEqual([[1,2],3], undefined)
false
arraysEqual(undefined, undefined)
true
arraysEqual(1, 2)
false
arraysEqual(null, null)
true
arraysEqual(1, 1)
true
arraysEqual([], 1)
false
arraysEqual([], undefined)
false
arraysEqual([], [])
true

Если вы хотите применить это к JSON-подобным структурам данных с помощью js Objects, вы можете сделать это. К счастью, мы гарантируем, что все ключи объектов являются уникальными, поэтому перебираем объекты OwnProperties и сортируем их по ключу, затем утверждаем, что оба отсортированных ключа-массива равны, а массив значений равны, и просто повторяем. Мы можем расширить это, чтобы включить Карты (где ключи также уникальны). (Однако, если мы расширим это до множеств, мы столкнемся с проблемой изоморфизма дерева http://logic.pdmi.ras.ru/~smal/files/smal_jass08_slides.pdf — к счастью, это не так сложно, как обычно Изоморфизм графа ; на самом деле существует алгоритм O (# вершин) для его решения, но это может быть очень сложно сделать это эффективно. Патологический случай, если у вас есть набор, состоящий из много, казалось бы, неотличимых объектов, но при дальнейшей проверке некоторые из этих объектов могут отличаться, если углубиться в них. Вы также можете обойти это, используя хеширование для отклонения почти всех случаев.)


Вариант 4: (продолжение 2016 г. edit)

Это должно работать с большинством объектов:

function deepEquals(a,b) {
    if (a instanceof Array && b instanceof Array)
        return arraysEqual(a,b);
    if (Object.getPrototypeOf(a)===Object.prototype && Object.getPrototypeOf(b)===Object.prototype)
        return objectsEqual(a,b);
    if (a instanceof Map && b instanceof Map)
        return mapsEqual(a,b);        
    if (a instanceof Set && b instanceof Set)
        throw "Error: set equality by hashing not implemented."
    if ((a instanceof ArrayBuffer || ArrayBuffer.isView(a)) && (b instanceof ArrayBuffer || ArrayBuffer.isView(b)))
        return typedArraysEqual(a,b);
    return a==b;  // see note[1] -- IMPORTANT
}

function arraysEqual(a,b) {
    if (a.length!=b.length)
        return false;
    for(var i=0; i<a.length; i  )
        if (!deepEquals(a[i],b[i]))
            return false;
    return true;
}
function objectsEqual(a,b) {
    var aKeys = Object.getOwnPropertyNames(a);
    var bKeys = Object.getOwnPropertyNames(b);
    if (aKeys.length!=bKeys.length)
        return false;
    aKeys.sort();
    bKeys.sort();
    for(var i=0; i<aKeys.length; i  )
        if (aKeys[i]!=bKeys[i]) // keys must be strings
            return false;
    return deepEquals(aKeys.map(k=>a[k]), aKeys.map(k=>b[k]));
}
function mapsEqual(a,b) {
    if (a.size!=b.size)
        return false;
    var aPairs = Array.from(a);
    var bPairs = Array.from(b);
    aPairs.sort((x,y) => x[0]<y[0]);
    bPairs.sort((x,y) => x[0]<y[0]);
    for(var i=0; i<a.length; i  )
        if (!deepEquals(aPairs[i][0],bPairs[i][0]) || !deepEquals(aPairs[i][1],bPairs[i][1]))
            return false;
    return true;
}
function typedArraysEqual(a,b) {
    a = new Uint8Array(a);
    b = new Uint8Array(b);
    if (a.length != b.length)
        return false;
    for(var i=0; i<a.length; i  )
        if (a[i]!=b[i])
            return false;
    return true;
}

Демонстрация (не тестировалась всесторонне):

var nineTen = new Float32Array(2);
nineTen[0]=9; nineTen[1]=10;
deepEquals(
    [[1,[2,3]], 4, {a:5,b:6}, new Map([['c',7],['d',8]]), nineTen],
    [[1,[2,3]], 4, {b:6,a:5}, new Map([['d',8],['c',7]]), nineTen]
)

(sidenote: Карты являются словарями es6. Я не могу сказать, есть ли у них O (1) или O (log ( N)) производительность поиска, но в любом случае они «упорядочены» в том смысле, что они отслеживают порядок, в котором пары ключ-значение были вставлены в них. Однако семантика того, должны ли две карты быть равными если элементы были вставлены в другом порядке в них неоднозначно. Ниже приведен пример реализации deepEquals, в котором две карты считаются равными, даже если элементы были вставлены в них в другом порядке.)

(Примечание [1]: ВАЖНО: УВЕДОМЛЕНИЕ О РАВЕНСТВЕ: вы можете переопределить отмеченную строку с пользовательским понятием равенства, которое вам также придется изменить в других функциях, где бы оно ни появилось. Например, хотите или не хотите NaN == NaN? По умолчанию это не так. более странные вещи, такие как 0 == ‘0’. Считаете ли вы два объекта одинаковыми, если и только если они являются одним и тем же объектом в памяти? См. https://stackoverflow.com/a/5447170/711085 { *}. Вы должны задокументировать понятие равенства, которое вы используете.) Вы должны быть в состоянии распространить вышесказанное на WeakMaps, WeakSets. Не уверен, имеет ли смысл распространяться на DataViews. Также должно быть возможно расширение до RegExps и т. Д.

По мере его расширения вы понимаете, что делаете много ненужных сравнений. Здесь функция

, которую я определил ранее (решение # 2), может пригодиться ;, тогда вы можете отправить ее мгновенно. Стоит ли это накладных расходов (возможно? Не знаю, как это работает под капотом) строки, представляющей тип, зависит от вас. Затем вы можете просто переписать диспетчер, то есть функцию type, примерно так: deepEquals jQuery не имеет метода для сравнения массивов. Однако

var dispatchTypeEquals = {
    number: function(a,b) {...a==b...},
    array: function(a,b) {...deepEquals(x,y)...},
    ...
}
function deepEquals(a,b) {
    var typeA = extractType(a);
    var typeB = extractType(a);
    return typeA==typeB && dispatchTypeEquals[typeA](a,b);
}

библиотека Underscore (или аналогичная библиотека Lodash) имеет такой метод: isEqual isEqual , и он может также обрабатывать множество других случаев (например, объектные литералы). Чтобы придерживаться предоставленного примера:

var a=[1,2,3];
var b=[3,2,1];
var c=new Array(1,2,3);

alert(_.isEqual(a, b)   "|"   _.isEqual(b, c));

Кстати: в Underscore есть много других методов, которые также отсутствуют в jQuery, поэтому это отличное дополнение к jQuery.

Мы только что выпустили Как было отмечено в комментариях, вышеприведенное теперь работает только в том случае, если оба массива имеют свои элементы в одном и том же порядке, т. Е .:

_.isEqual([1,2,3], [1,2,3]); // true
_.isEqual([1,2,3], [3,2,1]); // false

К счастью, в Javascript есть встроенный метод для решения этой точной проблемы, Для простых значений, таких как числа и строки, это простое решение: sort:

_.isEqual([1,2,3].sort(), [3,2,1].sort()); // true

Вызов

a = [1,2,3]

b = [3,2,1]

a.sort().toString() == b.sort().toString() 

гарантирует, что порядок элементов не имеет значения. Вызов sort() создаст строку с разделенными запятыми значениями, чтобы обе строки можно было проверить на равенство. toString() С версией JavaScript 1.6 это так просто:

Например,

Array.prototype.equals = function( array ) {
  return this.length == array.length && 
         this.every( function(this_i,i) { return this_i == array[i] } )  
  }

Даже если это кажется очень простым, иногда это действительно полезно. Если все, что вам нужно, это проверить, имеют ли два массива одинаковые элементы и они находятся в одном и том же порядке, попробуйте следующее: [].equals([]) дает true Вы можете создать HTML самостоятельно, вам не нужен JavaScript для написания HTML. Это было бы глупо, если бы люди предложили это. [1,2,3].equals( [1,3,2] ): false Глядя на вывод

Однако это не работает для сложных режимов, например:

[1, 2, 3].toString() == [1, 2, 3].toString()
true
[1, 2, 3,].toString() == [1, 2, 3].toString()
true
[1,2,3].toString() == [1, 2, 3].toString()
true

Это зависит от того, что вам нужно ,

[[1,2],[3]].toString() == [[1],[2,3]].toString()
true

Исходя из ответа Тима Джеймса

Основано на Тиме Джеймсе и комментария Fox32, следующее должно проверять наличие нулей, предполагая, что два нуля не равны. jQuery имеет такой метод

function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); }

> arrays_equal([1,2,3], [1,3,4])
false
> arrays_equal([1,2,3], [1,2,3])
true
> arrays_equal([1,3,4], [1,2,3])
false
> arrays_equal(null, [1,2,3])
false
> arrays_equal(null, null)
false

Домашняя проверка общего назначения для глубокого рекурсивного сравнения Глядя на вывод

строгого равенства может выглядеть следующим образом: Тесты:

function deepEquals(obj1, obj2, parents1, parents2) {
    "use strict";
    var i;
    // compare null and undefined
    if (obj1 === undefined || obj2 === undefined || 
        obj1 === null || obj2 === null) {
        return obj1 === obj2;
    }

    // compare primitives
    if (typeof (obj1) !== 'object' || typeof (obj2) !== 'object') {
        return obj1.valueOf() === obj2.valueOf();
    }

    // if objects are of different types or lengths they can't be equal
    if (obj1.constructor !== obj2.constructor || (obj1.length !== undefined && obj1.length !== obj2.length)) {
        return false;
    }

    // iterate the objects
    for (i in obj1) {
        // build the parents list for object on the left (obj1)
        if (parents1 === undefined) parents1 = [];
        if (obj1.constructor === Object) parents1.push(obj1);
        // build the parents list for object on the right (obj2)
        if (parents2 === undefined) parents2 = [];
        if (obj2.constructor === Object) parents2.push(obj2);
        // walk through object properties
        if (obj1.propertyIsEnumerable(i)) {
            if (obj2.propertyIsEnumerable(i)) {
                // if object at i was met while going down here
                // it's a self reference
                if ((obj1[i].constructor === Object && parents1.indexOf(obj1[i]) >= 0) || (obj2[i].constructor === Object && parents2.indexOf(obj2[i]) >= 0)) {
                    if (obj1[i] !== obj2[i]) {
                        return false;
                    }
                    continue;
                }
                // it's not a self reference so we are here
                if (!deepEquals(obj1[i], obj2[i], parents1, parents2)) {
                    return false;
                }
            } else {
                // obj2[i] does not exist
                return false;
            }
        }
    }
    return true;
};

Проверять каждое каждое значение в цикле for после проверки размера массив.

// message is displayed on failure
// clean console === all tests passed
function assertTrue(cond, msg) {
    if (!cond) {
        console.log(msg);
    }
}

var a = 'sdf',
    b = 'sdf';
assertTrue(deepEquals(b, a), 'Strings are equal.');
b = 'dfs';
assertTrue(!deepEquals(b, a), 'Strings are not equal.');
a = 9;
b = 9;
assertTrue(deepEquals(b, a), 'Numbers are equal.');
b = 3;
assertTrue(!deepEquals(b, a), 'Numbers are not equal.');
a = false;
b = false;
assertTrue(deepEquals(b, a), 'Booleans are equal.');
b = true;
assertTrue(!deepEquals(b, a), 'Booleans are not equal.');
a = null;
assertTrue(!deepEquals(b, a), 'Boolean is not equal to null.');
a = function () {
    return true;
};
assertTrue(deepEquals(
[
    [1, 1, 1],
    [2, 'asdf', [1, a]],
    [3, {
        'a': 1.0
    },
    true]
], 
[
    [1, 1, 1],
    [2, 'asdf', [1, a]],
    [3, {
        'a': 1.0
    },
    true]
]), 'Arrays are equal.');
assertTrue(!deepEquals(
[
    [1, 1, 1],
    [2, 'asdf', [1, a]],
    [3, {
        'a': 1.0
    },
    true]
],
[
    [1, 1, 1],
    [2, 'asdf', [1, a]],
    [3, {
        'a': '1'
    },
    true]
]), 'Arrays are not equal.');
a = {
    prop: 'val'
};
a.self = a;
b = {
    prop: 'val'
};
b.self = a;
assertTrue(deepEquals(b, a), 'Immediate self referencing objects are equal.');
a.prop = 'shmal';
assertTrue(!deepEquals(b, a), 'Immediate self referencing objects are not equal.');
a = {
    prop: 'val',
    inside: {}
};
a.inside.self = a;
b = {
    prop: 'val',
    inside: {}
};
b.inside.self = a;
assertTrue(deepEquals(b, a), 'Deep self referencing objects are equal.');
b.inside.self = b;
assertTrue(!deepEquals(b, a), 'Deep self referencing objects are not equeal. Not the same instance.');
b.inside.self = {foo: 'bar'};
assertTrue(!deepEquals(b, a), 'Deep self referencing objects are not equal. Completely different object.');
a = {};
b = {};
a.self = a;
b.self = {};
assertTrue(!deepEquals(b, a), 'Empty object and self reference of an empty object.');

Если вы используете lodash и не хотите изменять ни один массив, вы можете использовать

function equalArray(a, b) {
    if (a.length === b.length) {
        for (var i = 0; i < a.length; i  ) {
            if (a[i] !== b[i]) {
                return false;
            }
        }
        return true;
    } else {
        return false;
    }
}

массивов map() и reduce():

function arraysEqual (a1, a2) {
    return a1 === a2 || (
        a1 !== null && a2 !== null &&
        a1.length === a2.length &&
        a1
            .map(function (val, idx) { return val === a2[idx]; })
            .reduce(function (prev, cur) { return prev && cur; }, true)
    );
}

функцию _.xor () Нет простого способа сделать это. Мне это тоже нужно, но мне нужна функция, которая может принимать любые две переменные и проверять на равенство. Это включает необъектные значения, объекты, массивы и любой уровень вложенности. . Он сравнивает два массива как наборы и возвращает набор, содержащий их различие. Если длина этой разности равна нулю, два массива по существу равны:

var a = [1, 2, 3];
var b = [3, 2, 1];
var c = new Array(1, 2, 3);
_.xor(a, b).length === 0
true
_.xor(b, c).length === 0
true

В вашем вопросе вы упомянули о желании игнорировать порядок значений в массиве. Мое решение по своей сути не делает этого, но вы можете достичь этого путем сортировки массивов перед сравнением на равенство

Я также хотел опцию приведения не-объектов к строкам, чтобы [1,2] === [«1 «, 2]

Поскольку мой проект использует UnderscoreJs, я решил сделать его миксином, а не отдельной функцией.

Вы можете проверить это на

http://jsfiddle.net/nemesarial/T44W4/ Вот мой mxin:

Вот как вы его используете:

_.mixin({
  /**
  Tests for the equality of two variables
    valA: first variable
    valB: second variable
    stringifyStatics: cast non-objects to string so that "1"===1
  **/
  equal:function(valA,valB,stringifyStatics){
    stringifyStatics=!!stringifyStatics;

    //check for same type
    if(typeof(valA)!==typeof(valB)){
      if((_.isObject(valA) || _.isObject(valB))){
        return false;
      }
    }

    //test non-objects for equality
    if(!_.isObject(valA)){
      if(stringifyStatics){
        var valAs='' valA;
        var valBs='' valB;
        ret=('' valA)===('' valB);
      }else{
        ret=valA===valB;
      }
      return ret;
    }

    //test for length
    if(_.size(valA)!=_.size(valB)){
      return false;
    }

    //test for arrays first
    var isArr=_.isArray(valA);

    //test whether both are array or both object
    if(isArr!==_.isArray(valB)){
      return false;
    }

    var ret=true;
    if(isArr){
      //do test for arrays
      _.each(valA,function(val,idx,lst){
        if(!ret){return;}
        ret=ret && _.equal(val,valB[idx],stringifyStatics);
      });
    }else{
      //do test for objects
      _.each(valA,function(val,idx,lst){
        if(!ret){return;}

        //test for object member exists
        if(!_.has(valB,idx)){
          ret=false;
          return;
        }

        // test for member equality
        ret=ret && _.equal(val,valB[idx],stringifyStatics);
      });

    }
    return ret;
  }
});

Чтобы продемонстрировать вложение, вы может сделать это:

_.equal([1,2,3],[1,2,"3"],true)

Если вы хотите проверить

_.equal(
    ['a',{b:'b',c:[{'someId':1},2]},[1,2,3]],
    ['a',{b:'b',c:[{'someId':"1"},2]},["1",'2',3]]
,true);

массивы объектов на равенство , и порядок НЕ имеет значения, то есть вы сначала захотите отсортировать массивы.

areEqual([{id: "0"}, {id: "1"}], [{id: "1"}, {id: "0"}]) // true

имеет все инструменты, которые вам понадобятся, объединяя Если второй аргумент не задан, он вернет пустой объект с первым аргументом, который будет использоваться в качестве прототипа возвращаемого объекта (первый объект, который будет использоваться в прототипе возвращаемого объекта цепь). РЕДАКТИРОВАТЬ: так как sortBy и isEqual:

// arr1 & arr2: Arrays of objects 
// sortProperty: the property of the object with which you want to sort
// Note: ensure every object in both arrays has your chosen sortProperty
// For example, arr1 = [{id: "v-test_id0"}, {id: "v-test_id1"}]
// and          arr2 = [{id: "v-test_id1"}, {id: "v-test_id0"}]
// sortProperty should be 'id'

function areEqual (arr1, arr2, sortProperty) {
  return _.areEqual(_.sortBy(arr1, sortProperty), _.sortBy(arr2, sortProperty))
}

возвращает новый массив, нет необходимости клонировать ваши массивы перед сортировкой. Исходные массивы не будут видоизменяться. sortBy Обратите внимание, что для

порядка Лодаша имеет значение isEqual, . В приведенном выше примере будет возвращаться не применяется к каждому массиву в первую очередь. false Мы также можем добавить sortBy Он обрабатывает все возможные вещи и даже ссылается на себя в структуре объекта. Вы можете увидеть пример в конце кода.

Этот метод отстой, но я оставил его здесь для справки, поэтому другие избегают этого пути:

var deepCompare = (function() {
    function internalDeepCompare (obj1, obj2, objects) {
        var i, objPair;

        if (obj1 === obj2) {
            return true;
        }

        i = objects.length;
        while (i--) {
            objPair = objects[i];
            if (  (objPair.obj1 === obj1 && objPair.obj2 === obj2) ||
                  (objPair.obj1 === obj2 && objPair.obj2 === obj1)  ) {                          
                return true;
            }                    
        }
        objects.push({obj1: obj1, obj2: obj2});

        if (obj1 instanceof Array) {
            if (!(obj2 instanceof Array)) {
                return false;
            }

            i = obj1.length;

            if (i !== obj2.length) {
               return false; 
            }

            while (i--) {
                if (!internalDeepCompare(obj1[i], obj2[i], objects)) {
                    return false;
                }
            }
        }
        else {
            switch (typeof obj1) {
                case "object":                
                    // deal with null
                    if (!(obj2 && obj1.constructor === obj2.constructor)) {
                        return false;
                    }

                    if (obj1 instanceof RegExp) {
                        if (!(obj2 instanceof RegExp && obj1.source === obj2.source)) {
                            return false;
                        }
                    }                 
                    else if (obj1 instanceof Date) {
                        if (!(obj2 instanceof Date && obj1.getTime() === obj2.getTime())) {
                            return false;
                        }
                    } 
                    else {    
                        for (i in obj1) {
                            if (obj1.hasOwnProperty(i)) {       
                                if (!(obj2.hasOwnProperty(i) && internalDeepCompare(obj1[i], obj2[i], objects))) {
                                    return false;
                                }
                            }
                        }         
                    }
                    break;
                case "function": 
                    if (!(typeof obj2 === "function" && obj1 "" === obj2 "")) {
                        return false;
                    }
                    break;
                default:                 //deal with NaN 
                    if (obj1 !== obj2 && obj1 === obj1 && obj2 === obj2) {
                        return false;            
                    }
            }
        }

        return true;
    }

    return function (obj1, obj2) {
        return internalDeepCompare(obj1, obj2, []);    
    };
}());

/*    
var a = [a, undefined, new Date(10), /. /, {a:2}, function(){}, Infinity, -Infinity, NaN, 0, -0, 1, [4,5], "1", "-1", "a", null],
    b = [b, undefined, new Date(10), /. /, {a:2}, function(){}, Infinity, -Infinity, NaN, 0, -0, 1, [4,5], "1", "-1", "a", null];
deepCompare(a, b);
*/

Использование варианта 1 из @ninjagecko лучше всего работает для меня:


Он также будет обрабатывать нулевой и неопределенный регистр, так как мы добавляем это в прототип массива и проверяем, что другой аргумент также является массивом.

Array.prototype.equals = function(array) {
    return array instanceof Array && JSON.stringify(this) === JSON.stringify(array) ;
}

a = [1, [2, 3]]
a.equals([[1, 2], 3]) // false
a.equals([1, [2, 3]]) // true

Не тот ответ, который вы ищете? Просмотрите другие вопросы с тегом

var a= [1, 2, 3, '3'];
var b = [1, 2, 3];

var c = a.filter(function (i) { return ! ~b.indexOf(i); });

alert(c.length);

javascript . Для разработки ответа Стивена Спилберга я сделал это в таком случае: { *} Выражение задайте свой вопрос Глядя на вывод