簡體   English   中英

為什么這兩個函數有不同的結果?(對不起,我不知道如何描述它們)

[英]Why do these two functions have different results?(Sorry, I don't know how to describe them)

我有 2 個問題

  1. counter1()counter1()()有什么區別?
    counter1 不是已經是 function 名稱了嗎? 為什么是第二個()

  2. 為什么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

為了便於討論,讓innerCounter1counter1的返回值的名稱。 因此,以下代碼等同於您在示例中的代碼。

 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()時,局部變量( initValueinnerCounter1 )都是獨立的。 例如:

let counter1A = counter1();
let counter1B = counter1();

counter1A(); // 1
counter1A(); // 2
counter1B(); // 1
counter1B(); // 2

換句話說, counter1Acounter1B記住了一個單獨的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.

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