[英]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
為什么對函數的調用會像這樣嘈雜? (Boolean) 是演員表嗎? 演員表干什么? 返回值? 還是論點? 為什么不是 (Boolean)noisy(0) 如果它的返回值。 如果參數是被轉換的參數,則為noise((Boolean) 0)。
noisy(Boolean)(0)
這條線發生了什么? f() 在哪里定義?
var val = f(arg);
Boolean
是一個函數。 這是您通過noisy
間接調用的函數。 我知道這有點令人困惑,因為它看起來像一個類型的名稱。 但是在 JavaScript 中,那些最初限定的東西( Boolean
、 Number
、 String
等)是函數。 當您調用Boolean
(不使用new
)時,它會嘗試將您提供的參數轉換為boolean
原始值並返回結果。 (請參閱規范中的第15.6.1 節。)
f
是noisy
函數中參數的名稱。
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)
時傳入noisy
的Boolean
函數。 然后它被用作噪聲函數中的參數。 我也沒有意識到 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.