[英]Why am I getting two different results from two functions that don't seem different at all taking advantage of closures?
[英]Why do these two functions have different results?(Sorry, I don't know how to describe them)
我有 2 個問題
counter1()
和counter1()()
有什么區別?
counter1 不是已經是 function 名稱了嗎? 為什么是第二個()
?
為什么counter2能記住數值?
這是我的代碼:
const counter1 = function(){
let initValue = 0
return function(){
initValue++;
return initValue
}
}
const counter2 = (function(){
let initValue = 0
return function(){
initValue++;
return initValue
}
})()
console.log(counter1());
console.log(counter1()());
console.log(counter1()());
console.log(counter2());
console.log(counter2());
這是 output :
counter1
是一個 function ,它返回一個 function 或所謂的高階 function 。
為了便於討論,讓innerCounter1
為counter1
的返回值的名稱。 因此,以下代碼等同於您在示例中的代碼。
const counter1 = function(){
let initValue = 0
const innerCounter1 = function(){
initValue++;
return initValue
}
return innerCounter1;
}
counter1 不是已經是 function 名稱了嗎? 為什么是第二個()?
是的, counter1
是 function,但它也返回 function。 通過命名返回值innerCounter1
,我希望清楚的是,當您調用counter1()
時,您得到的值是innerCounter1
。 當你調用innerCounter1()
時,你得到的值是數字initValue
。 所以counter1()()
正在獲取innerCounter1
的值,並在一個簡短的表達式中調用該內部 function。
為什么counter2能記住數值?
When a function is created ( innerCounter1
in your example), and the function references value defined outside of the function ( initValue
in your example), a closure is created, which you can intuitively understand as "memorizing" the variable. 函數counter1()
和counter2
都記住了這個值,但這里要注意的是,每次調用counter1()
時,局部變量( initValue
和innerCounter1
)都是獨立的。 例如:
let counter1A = counter1();
let counter1B = counter1();
counter1A(); // 1
counter1A(); // 2
counter1B(); // 1
counter1B(); // 2
換句話說, counter1A
和counter1B
記住了一個單獨的initValue
變量,所以調用一個不會影響另一個。
而這個counter2
的定義: let counter2 = counter1();
, 相當於你上面的匿名 function 語法,所以應該清楚發生的事情與我上面解釋的counter1A
完全相同。
In JS
you can return a function from a function
which then can be used anywhere you want, add to that: that returned function can still access the variables where it was defined(can access its lexical scope variables) this feature is called closures.
請仔細閱讀帶有代碼的評論
const counter1 = function () {
let initValue = 0
return function () {
initValue++;
return initValue
}
}
/**
* is the same as
*/
function counter1() {
let initValue = 0
/** this function is returned */
return function () {
/**
* and can access the variable `initValue` at run time because at auth time its scope is inside
* the `counter1` scope where the variable is defined in
* (because inner scope can access outer scope defined in them)
*
*/
initValue++;
return initValue
}
}
/**
* as for using counter1
* in each time we call the `counter1` we get a reference to the inner anonymous function that has
* access to that variable but in each call we have new `initValue` variable that's why
* no matter how many times you call `counter1` you keep getting the same result because you have new
* `initValue` for each call
*/
const counter2 = (function () {
let initValue = 0
return function () {
initValue++;
return initValue
}
})()
/**
* this form of defining a function and immediately executing it called IIEF(Immediately invoked function expression)
*
* what this code is executed you have counter2 which is equal to the inner function returned from the outer function expression
*
*/
// naming anonymous functions for easing
const counter2 = (function IIFE_counter2() {
let initValue = 0
return function counter2_returned_function() {
initValue++;
return initValue
}
})()
/**
* no counter2 = counter2_returned_function
*
* so
* 1- it can access `initValue` each time it's called
* 2- for each call of counter2 we are not creating new instance of `IIFE_counter2` instead we just call the inner
* `counter2_returned_function` which still have the old value of `initValue` and can update it successfully
*/
請閱讀YDKJS
以獲取有關此主題的更多經驗https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch7.md
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.