数组相等性检查算法在某些情况下不起作用

时间:2011-02-12 14:03:39

标签: javascript arrays algorithm

我有一段代码可以检查数组是否相等。它在使用时就像魅力一样:

[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 个答案:

答案 0 :(得分:2)

这一行:

    if (this[i].equals) {

应该是:

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

因此如果this[i]undefined,您将不会尝试访问undefined上的媒体资源。


编辑:由于您似乎正在测试数组,因此执行更明确的测试会更安全,因为任何Object都可能具有.equals属性。

您可能希望这样做:

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

它有点长,但会准确地检测到一个数组,即使它是使用new关键字创建的,这会甩掉typeof运算符。