首先,它有助于理解为什么$.inArray()
不起作用。让我们尝试一个更简单的案例。将其粘贴到浏览器中加载了 jQuery 的页面上的 JavaScript 控制台(例如我们所在的这个页面)并运行它:
var object = { a: 1 };
var array = [ { a: 1 } ];
console.log( '$.inArray: ', $.inArray( object, array ) );
(注意术语:你的group
变量是一个对象,而不是一个数组。)
现在它看起来像object
在数组中,对吧?那为什么要打印-1
呢?试试这个:
console.log( object );
console.log( array[0] );
它们看起来一样。怎么样:
console.log( '== or === works? ', object == array[0], object === array[0] );
或者更简单:
console.log( 'Does {a:1} == {a:1}? ', {a:1} == {a:1} );
console.log( 'What about {} == {}? ', {} == {} );
那些都打印false
!
这是因为两个碰巧具有相同内容的对象仍然是两个独立的对象,而当您使用==
或===
比较两个对象时,您实际上是在测试它们是否都是对同一个对象的引用。两个不同的对象永远不会比较相等,即使它们包含完全相同的内容。
$.inArray()
就像使用===
运算符比较两个对象一样 - 它不会在数组中找到对象,除非它是相同的对象,而不仅仅是具有相同内容的对象。
知道了这一点,这是否暗示了解决问题的任何可能方法?您可以通过多种方式编写自己的代码来搜索数组中的对象,或者您可能会发现使用诸如Underscore.js之类的库很有帮助,该库具有许多有用的数组和对象方法。
例如,您可以使用_.findWhere( groupsArray, group )
来查找第一个匹配项 - 需要注意的是它只比较对象中的group
属性。例如,如果group
is {a:1}
,它将匹配groupsArray
数组中的对象是{a:1,b:2}
。
如果您需要完全匹配,您可以结合下划线_.find()
和_.isEqual()
方法:
var index = _.find( groupsArray, function( element ) {
return _.isEqual( element, group );
});
现在要注意的最后一件事。您将group
对象推送到groupsArray
数组上的代码 - 您知道推送实际group
对象本身。它不会在数组中复制它,它是对同一个对象的引用。(具有讽刺意味的是,这意味着您group
在数组中查找的原始代码实际上可以在您自己将同一个group
对象推送到数组的情况下工作。)
如果您想确保其中的groupsArray
每个元素都是它们自己的独立对象,而不是对代码中浮动的另一个对象的引用,您可以使用另一个 Underscore 方法进行浅拷贝:
groupsArray.push( _.clone(group) );
但是,如果group
有任何嵌套对象,则不会复制它们。(我在 Underscore 中没有看到深拷贝功能,但如果需要,您可以编写一个。)