簡體   English   中英

為什么不“返回”打破我的循環?

[英]Why isn't 'return' breaking my loop?

這是我要通過的測試:

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;  
};

我相信我在發生功能中正在做的事情:

  1. 接受參數(數組和函數
  2. 遍歷數組(在forEach中)
  3. 如果blah(el)不是true,則返回false(這是否會中斷循環並在傳入的函數求值為false時返回false?
  4. 如果沒有任何假值,則返回true
  5. **我目前沒有為空數組實現的案例。

我是否想知道回報如何運作? 我在下面(鏈接)提供了一個repl.it會話。 我在if語句中包含了console.log,當值為false時返回“ false”,但返回值仍然不會輸出或中斷循環。

http://repl.it/NjH/1

forEach不會在Javascript中返回值-當您返回false ,您只是從forEach的回調中返回false 該值將被忽略。

相反,如果使用兼容的實現(例如Node / Webkit /支持ECMAScript 5的東西Array.every()則可以嘗試Array.every()

否則,在forEach外部設置信號量變量,如果blah(el)返回false,則將其設置為false。 然后在forEach完成后檢查變量的值。

您不會錯過關於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 ,這與循環完全無關。

它說“ forEach”,它將為您帶來一遍遍數組中的每一項(在調用函數時存在)。

核心問題是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;
};

不過說真的,改變(內/外否定和條件, someevery ):

var occur = function(array, blah){
  return array.every(function(el){
    return blah(el);
  });
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM