如果forEach的匿名函数内的条件不起作用

时间:2016-07-08 19:23:04

标签: javascript foreach

请考虑以下代码段:

function isUniform(myArray) {
    myArray.forEach(function(element) {
        if (element !== myArray[0]) {
            return false;
        }
    });

    return true;
}

意图是函数应该将数组作为输入,如果数组中的所有元素都相同,则返回true,否则返回false

例如:

isUniform([1,2,1,1]); //应该返回false isUniform([1,1,1,1]); //应该返回true

然而,if条件:

if (element !== myArray[0])
在isUniform([1,2,1,1])的情况下,

似乎永远不会成真。

我错过了什么?

1 个答案:

答案 0 :(得分:5)

因此return true没有返回函数isUniform的值,它会为您提供给forEach方法的回调返回一个值。 forEach实际上只用于创建副作用。所以forEach对每个元素执行回调,看到回调返回false,但后来没有与该值有任何关系,所以它抛出它然后继续下一个数组中的元素。在遍历数组之后,它继续到下一行代码并返回函数的true

使用forEach执行此操作的一种方法是声明一个初始化为true的变量,并在回调中操作该变量。这是必要的,因为没有办法尽早结束forEach循环的执行。所以你可以改用:

function isUniform(myArray) {
    var passing = true;
    myArray.forEach(function(element) {
        if (element !== myArray[0]) {
            passing = false;
        }
    });

    return passing;
}

或者你可以使用for循环或for-of循环,在这种情况下return语句可以像你原先预期的那样工作。您可能已经熟悉for循环。 ES2015中引入了For-of循环(因此它们可能无法在所有JS引擎上运行)。 for-of循环看起来像这样:

function isUniform(myArray) {
    for (element of myArray) {
        if (element !== myArray[0]) {
            return false
        }
    }
    return true
}

但是,执行此操作的最佳方法可能是使用内置数组方法every,如果数组中的每个元素都通过了回调中提供的测试,则返回true。因此,您可以测试每个元素,看它们是否等于数组中的第0个元素,因此彼此相等:

function isUniform(myArray) {
    return myArray.every(function (currentElement,index,array) {
        return currentElement === array[0]
    })
}

这很短,你甚至不需要把它放在自己的功能中 - 如果你不这样做,你的代码可能会更具可读性。

文档: Array.prototype.every:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every

for-of循环:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of