为什么在条件为假时执行JavaScript代码? (雄辩的JavaScript - 深度比较)

时间:2015-04-25 21:03:31

标签: javascript function if-statement

问题(Eloquent JS第2版,第4章,练习4):

  

编写一个函数deepEqual,它接受两个值并返回true   只有它们是相同的值或具有相同的对象   与递归相比,其值也相等的属性   打电话给deepEqual。

测试案例:

var obj = {here: {is: "an"}, object: 2};
var obj1 = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj,obj1));

代码:

var deepEqual = function (x, y) {
    if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) {
        if (Object.keys(x).length != Object.keys(y).length)
          return false;

        for (var prop in x) {
          if (y.hasOwnProperty(prop)){  
            if (! deepEqual(x[prop], y[prop])) //should not enter!!
                return false;
                alert('test');
          }else return false; // What does this section do?
        }
        return true;
    }
    else if (x !== y)
        return false;
    else
        return true;
};

最初由Paul Roub

履行

主要问题:我刚刚将{em> alert 添加到if (! deepEqual(x[prop], y[prop]))语句后的代码块中,就像调试一样,现在我不知道为什么代码里面有仍然执行语句本身应该返回true!将其转换为false ..?
此外:什么是}else return false;? (同样的陈述)没有这一部分,该功能似乎工作正常..

1 个答案:

答案 0 :(得分:6)

您添加alert()只会在if测试失败时运行,因为您没有添加{ }来匹配你的缩进表明的意图。如果if测试成功,则以下return语句将退出该函数,alert()将不会发生。

任何涉及始终返回ifelse if块的代码,但后面跟着else子句都是代码气味。 elsereturn是多余的;你去的方式是风格问题。

该代码也有缺陷,因为它使用Object.keys()测试属性的数量 - 隐式只查看“自己的”属性 - 然后使用for ... in循环遍历x 没有 .hasOwnProperty()支票。 (遗传属性是否应该影响“平等”的概念是主观的,但它至少应该是对称的。)

哦,检查后的第一个else return false子句,看看y是否有x中的某个属性只是一个快速退出。如果y没有x中的属性名称,则它们不能相等。

最后请注意,任何想要通用的“深度”相等测试人员确实需要处理对象图周期和其他更奇怪的东西。 (x的对象图中的某些内容指的是y的一部分,反之亦然?)深层对象比较不是一件小事。