簡體   English   中英

雄辯的JavaScript,第二版,第5章高階函數

[英]Eloquent JavaScript, 2nd Edition, Chapter 5 Higher-Order Functions

我是JavaScript的新手,我希望在第二版的第5章中獲得一些幫助。 雄辯的JavaScript。 具體來說,我遇到了以下示例:

function noisy(f) {
  return function(arg) {
    console.log("calling with", arg);
    var val = f(arg);
    console.log("called with", arg, "- got", val);
    return val;
  };
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false

我想我理解生成其他函數的高階函數的概念,但是不確定我是否理解“捕獲”的概念以及它在這里的含義。 具體來說, var val = f(arg);

有人可以引導我瀏覽該行代碼嗎? 您如何將一個參數傳遞給另一個參數? 我不確定我是否使用了正確的術語,所以如果我記錯了,請原諒。 我只是不明白那條線,無法輕易找到與此主題相關的其他主題。

謝謝!

noisy是一個函數,它引用另一個函數f並返回一個包裝f的新函數,以便將其調用和返回值記錄到控制台。

val是調用函數f的結果,其中f是調用noisy時傳遞的函數引用。

要逐步進行:

// noisy accepts argument f (where f itself appears to be a function)
function noisy(f) {
    // noisy returns a new function that takes an argument arg
    return function(arg) {
        // when this new function is called, it logs to console
        console.log("calling with", arg);
        // the function you originally passed to noisy is now called, with the return value stored in val
        var val = f(arg);
        // return value val also logged to console
        console.log("called with", arg, "- got", val);
        // return value val is returned from the generated function
        return val;
    };
}
// noisy is called with the inbuilt function Boolean and the argument 0 (to test the boolean value of 0)
noisy(Boolean)(0);

另一個用例可能是這樣的:

function someFuncToMonitor(someArg) {
    return someArg + 1;
}
monitoredFunc = noisy(someFuncToMonitor);
result = monitoredFunc(5);
// calling with 5
// calling with 5 - got 6

因此,在短期呼叫monitoredFunc調用你的someFuncToMonitor功能為你,並告訴你關於呼叫和結果。

有問題的代碼:

function noisy(f) {
  return function(arg) {
    console.log("calling with", arg);
    var val = f(arg);
    console.log("called with", arg, "- got", val);
    return val;
  };
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false

發生了什么(類似於通過JavaScript進行的“神奇的校車”之旅):

  1. 直到代碼行noisy(Boolean)(0);才實際執行任何操作noisy(Boolean)(0);
  2. 到達此行時,首先使用JavaScript內置函數Boolean作為其參數f調用noisy函數。
  3. 返回一個匿名函數:
    • 運行時,匿名函數會收到一個稱為arg的新參數。
    • 然后匿名函數將記錄字符串“ calling with”,后跟arg
    • 然后匿名函數將調用函數f (已通過閉包在匿名函數中進行了記憶)並將返回值存儲在變量val
    • 然后匿名函數將記錄字符串“ with with”,后跟arg ,后跟字符串“ -get”,后跟val
    • 最后,匿名函數還將返回變量val的值。
  4. 如上所述, noisy(Boolean)的返回值是匿名函數, Boolean在剛剛生成的該匿名函數中扮演f的角色。
  5. 剩余的(0)現在用於以參數arg 0調用此新生成的匿名函數。
  6. 遵循上面3.中描述的五個子步驟,結果是:
    • 沒有可見的輸出,但是arg的值為0作為匿名函數調用的第一步。
    • 匿名函數記錄字符串“用0呼叫”
    • Boolean函數使用參數0運行,該參數返回false ,並將其存儲到val
    • 匿名函數記錄字符串“用0調用-得到假”
    • 匿名函數返回false (但是示例代碼未以任何方式使用或存儲此值)。

現在,讓我們看一下實際的代碼行,並將其與上述步驟匹配:

  1. 此代碼開始執行: noisy(Boolean)
  2. 執行noisy的以下代碼,將Boolean參數傳遞給noisy並存儲到變量f

     return function(arg) { console.log("calling with", arg); var val = f(arg); console.log("called with", arg, "- got", val); return val; }; 
  3. 此代碼的noisy(Boolean)部分noisy(Boolean)(0); 現在已替換為步驟2中顯示的返回值。
  4. 因此,現在noisy(Boolean)(0)實際上已成為[[anonymous function]](0)
  5. 現在執行此替換“代碼” [[anonymous function]](0)
  6. 結果,將執行以下代碼行:

      console.log("calling with", 0); // because 0 was passed in for arg var val = Boolean(0); // because Boolean is stored in f console.log("called with", 0, "- got", false); // because the Boolean value of 0 is false 

噪聲函數采用單個參數f ,該參數為函數。 當您調用noisy時,它將返回一個新函數(這意味着noisy(Boolean)返回一個函數)。 之所以進行捕獲是因為新函數可以訪問任何嘈雜的參數,包括f參數(程序員將此概念稱為閉包)。 當您有noisy(Boolean)(1) ,內部函數中的f引用Boolean 因此,由於var val = f(arg) ,所以val設置為Boolean(1) var val = f(arg)

暫無
暫無

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

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