1

我正在尝试创建一个递归函数,它将遍历多维对象并测试密钥是否存在于单独的对象中。如果键不存在我想打破循环并返回false,如果所有键都存在我想返回true。

我遇到的问题是该函数似乎总是返回 true。这是我正在使用的代码:

var properties = {'global': {'structure' : {'body': {}}}};

var testExists = {'global': {'structure': {'test': 'value'}}};

if( ! this.exists(properties, testExists)) {
   console.log("DOESNT EXIST");
}


exists: function(destination, source) {
    var exists = true;

    check:
    for (var property in source) {

        if(destination[property]) {
            arguments.callee(destination[property], source[property]);
        }
        else
        {
            exists = false;
            break check;
        }
    }

    console.log(exists);

    return exists;
},

当我查看控制台以查看“存在”的值时,我看到两行第一行是假的,第二行是真的,所以我正在创建的递归一定有错误

4

2 回答 2

1

您的问题似乎是您没有使用递归调用函数的结果。

此外,您不应该使用arguments.callee,而是使用函数名称,并可能在枚举其属性之前检查参数是否为对象。您可能还想检查destination不在枚举中的属性source

尝试这个:

function equal(destination, source) {
    if (Object(destination)!==destination || Object(source)!==source)
        // at least one of them is a primitive value
        return destination == source; // maybe use strict equality === ?
    for (var prop in source)
        if (!(prop in destination) || !equal(source[prop], destination[prop]))
            return false;
    return true;
}
于 2012-10-01T10:56:26.867 回答
1

你让它变得比它需要的更复杂:

function exists(destination, source) {
    for (var property in source) {
        if(destination.hasOwnProperty(property)) {
            if (!exists(destination[property], source[property])) {
                return false;
            }
        } else {
            return false;
        }
    }

    return true;
}​

请注意, .hasOwnProperty 意味着这只会比较对象的直接属性,而不是从原型继承的属性。我以为这就是你要找的东西。

另请注意:它实际上使用递归调用的结果,它正确递归,它使用 .hasOwnProperty 而不是仅检查虚假性,并且它不使用中间变量来存储结果(这不会以递归方式工作无论如何,您正在使用它们)。

还有一件事:这只会“单向”,即不会检查目标中不在源中的任何属性。要检查这两种方式,您必须调用它两次或将其扩展为在两者上循环。

于 2012-10-01T10:57:46.610 回答