请考虑以下代码段:
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])的情况下,似乎永远不会成真。
我错过了什么?
答案 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