这是我试图通过的测试:
describe("occur", function() {
var getVal = function(i) { return i; };
var even = function(num) { return num % 2 === 0; };
it("should handle an empty set", function() {
expect(occur([], getVal) ).toEqual(true);
});
it("should handle a set that contains only true values", function() {
expect(occur([true, true, false], getVal)).toEqual(false);
});
it("should handle a set that contains one false value", function() {
expect(occur([true, true, true], getVal)).toEqual(true);
});
it("should handle a set that contains even numbers", function() {
expect(occur([0, 8, 32], even)).toEqual(true);
});
it("should handle a set that contains an odd number", function() {
expect(occur([0, 13, 68], even)).toEqual(false);
});
});
这是我的代码:
var forEach = function(array, action){
for (var i = 0; i < array.length; i ++){
action(array[i]);
}
};
var occur = function(array, blah){
forEach(array, function(el){
if(!blah(el)){
return false;
}
});
return true;
};
我相信我在发生的功能中所做的事情:
我是否错过了返回工作的诀窍?我在下面提供了一个repl.it会话(链接)。我在if语句中包含了一个console.log,当值为false时它会记录'false',但返回值仍然没有输出或打破循环。
答案 0 :(得分:1)
forEach
在Javascript中未返回值 - 当您返回false
时,您只是从false
的回调中返回forEach
。该值被忽略。
相反,如果您使用的是Node / Webkit等支持ECMAScript 5的兼容实现,则可以尝试Array.every()
。
否则,在forEach
之外设置一个信号量变量,如果blah(el)
返回false,则将其设置为false。然后在forEach
完成后检查变量的值。
答案 1 :(得分:1)
你不会错过关于return
的伎俩,你遗漏了关于.forEach
的伎俩。
对于每个基本上看起来像这样:
function forEach (action) {
var arr = this,
i = 0, l = arr.length;
for (; i < l; i += 1) {
action(arr[i], i, arr);
}
}
除此之外还有更多,但实际上,这就是它正在做的事情。
因此,如果action()
中包含return
语句(即使它没有,它只返回undefined
,那么它与循环无关。< / p>
它表示“forEach”,它会让你得到的是一个遍历数组中的每一个项目(在调用函数时存在)。
答案 2 :(得分:1)
核心问题是return
总是退出最近的封闭函数 - 而不是其他。
var occur = function(array, blah){ // <-- "outer" function
forEach(array, function(el){ // <-- callback to forEach / "enclosing" function
if(!blah(el)){
// This returns from the callback/enclosing function; it has no
// bearing on the outer function.
return false;
}
});
return true;
};
除非改变方法,否则可以使用变量解决此问题。
var occur = function(array, blah){
var ret = true;
forEach(array, function(el){
if(!blah(el)){
// Set the closed-over variable to false, so that when the return
// in the outer function is reached the correct value will be returned.
// (forEach will still iterate over every remaining item)
ret = false;
}
});
return ret;
};
现在,我的建议是使用Array.some
之类的东西(在ES5.1中,在IE9 +和每个现代浏览器中都支持)。
var occur = function(array, blah){
var any = array.some(function(el){
if(!blah(el)){
return true;
}
});
return !any;
};
但实际上,改变条件(内部/外部的否定以及some
到every
):
var occur = function(array, blah){
return array.every(function(el){
return blah(el);
});
};