簡體   English   中英

Javascript 中的高階函數

[英]Higher-order functions in Javascript

我正在閱讀 Eloquent 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
  1. 為什么對函數的調用會像這樣嘈雜? (Boolean) 是演員表嗎? 演員表干什么? 返回值? 還是論點? 為什么不是 (Boolean)noisy(0) 如果它的返回值。 如果參數是被轉換的參數,則為noise((Boolean) 0)。

     noisy(Boolean)(0)
  2. 這條線發生了什么? f() 在哪里定義?

     var val = f(arg);
  1. Boolean是一個函數。 這是您通過noisy間接調用的函數。 我知道這有點令人困惑,因為它看起來像一個類型的名稱。 但是在 JavaScript 中,那些最初限定的東西( BooleanNumberString等)是函數 當您調用Boolean使用new )時,它會嘗試將您提供的參數轉換為boolean原始值並返回結果。 (請參閱規范中的第15.6.1 節。)

  2. fnoisy函數中參數的名稱。

JavaScript 中的函數是一流的對象。 您可以將它們作為參數傳遞給其他函數,就像任何其他對象一樣。

當你做

noisy(Boolean)(0)

有兩件事正在發生。 第一的:

// (In effect, we're not really creating a variable...)
var x = noisy(Boolean);

這給了我們一個函數,當被調用時,它將使用我們給它的參數調用Boolean ,同時執行那些console.log語句。 這是您在noisy看到的函數( return function(arg)... );

然后我們調用該函數:

x(0);

這就是您看到控制台輸出的時候。 由於Boolean(0)false ,您會看到Boolean返回該值。

這是一個更簡單的例子:

function foo(bar) {
    bar();
}
function testing() {
    alert("testing got called");
}
foo(testing);

在那里,我將功能testing傳遞給foo 我在foo使用的參數名稱是bar 線條bar(); 調用函數。

沒有 () 的函數才是真正的函數。 帶有 () 的函數是對該函數的調用。 另請記住,JavaScript 是一種松散類型的語言,因此您無需聲明變量類型。 我在您的示例中添加了一些評論以嘗試提供幫助。

// We define a function named noisy that takes in an argument named f. We are expecting f to be a function but this isn't enforced till the interpreter throws an error. 
function noisy(f) {
// Noisy returns a single item, an anonymous function. That anonymous function takes in an argument named arg
  return function(arg) {
    console.log("calling with", arg);
// Our anonymous function then takes f (It can use f because its defined inside noisy, see closures for more details) and invokes it with the argument arg and stores the result in a variable named val. 
    var val = f(arg);
    console.log("called with", arg, "- got", val);
// It now returns val
    return val;
  };
}

那么noise(Boolean)(0) 的工作方式是這樣的

f 是函數布爾值

嘈雜的返回這樣的函數

function(arg) {
  var val = Boolean(arg);
  return val;
}

所以現在我們有

我們返回的函數(0)

它像正常一樣執行成為

function(0) {
  var val = Boolean(0); // false
  return val;
}

我對 JS 比較陌生,我也剛剛閱讀了 Eloquent Javascript,一旦我理解了函數的調用,我發現它更容易理解(回答你的第 1 點):

noisy(Boolean)(0);

noisy(Boolean)創建了一個新函數,並且(0)在它之后,因為它被作為參數傳遞到該新函數中。 如果您參考大於示例:

function greaterThan(n) {
  return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));

也可以這樣調用:

greaterThan(10)(11);

我希望能澄清您關於為什么這樣稱呼它的第一個問題。

對於第二個問題。 中的f

var val = f(arg);

是在輸入noisy(Boolean)時傳入noisyBoolean函數。 然后它被用作噪聲函數中的參數。 我也沒有意識到 Boolean 本身可以是一個函數,而不僅僅是一種數據類型。 正如其他人所說 - 它將您提供的參數轉換為布爾值並返回結果。

因此val變為Boolean(arg) ,它變為Boolean(0) ,其計算結果為false 如果你嘗試調用noisy(Boolean)(1); 你會看到它返回true console.log("called with", arg, "- got", val); 簡單地記錄參數(在這種情況下為 0)和評估它的結果(假)。

實際上,它已將布爾函數更改為記錄參數和結果並返回結果的函數。

我希望這有幫助。 只是寫它有助於我自己的理解。

Javascript 變量沒有靜態數據類型。 也可以為它們分配不同數據類型的變量。

JS 中沒有類型轉換的概念,如 JAVA 等。

() 在函數調用中對應於函數的調用。

在這里,Boolean 似乎是一個高階函數,它作為參數傳遞給有噪聲的函數。 噪聲函數的結果將是

 function(arg) { console.log("calling with", arg); var val = f(arg); console.log("called with", arg, "- got", val); return val; };

帶有 0 的第二個括號用於調用此結果。

在這里,在上面的函數中,注意下面的行。

 var val = f(arg);

這里,f 對應於之前傳遞的布爾函數。 arg 對應於 0。

由於返回了 val,因此表達式的結果將是 Booelan(0) 的結果。

如果你仍然有這個問題,這就是我的理解(它也讓我頭疼..)

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)

函數只是一個常規值。 上一句話是理解這里發生的事情的關鍵。

我們的 noise(f) 函數是一個值。 這就是它返回的內容。

noise(f) 返回一個帶有參數 (arg) 的函數。

noise(f) 也接受一個參數 (f)。 內部函數(從函數內部調用的函數)可以訪問傳遞給外部函數的變量和參數。

我們正在調用我們的外部函數並將參數布爾值傳遞給它。 我們的外部函數返回它的內部函數,它接受一個參數 (0)。 通過理解上面的內容,應該很清楚 Noise(Boolean(0)) 只會將一個參數傳遞給我們的外部函數,而不會將任何內容傳遞給我們的外部函數返回的內部函數。

真的很簡單。 現在我們理解了它,很難相信它讓我們開始如此頭疼...... */`

暫無
暫無

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

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