代码之家  ›  专栏  ›  技术社区  ›  ofey

需要JS闭包和范围链澄清

  •  2
  • ofey  · 技术社区  · 7 年前

    我正在学习JS和闭包的概念。

    在下面的代码中,内部子函数查找num和num1的值。接下来,解释器进入范围链,搜索它们。它在main()中查找,但看不到它们,所以它会转到main的参数中,在声明中看不到它们,但它们在调用中。这就是他们的来源。这就是我对代码工作原理的理解,对吗?

    谢谢

    function main() {
      return function child(num, num1) {
        console.log(num + num1);
      }
    }
    
    const result = main();
    result(2, 4); // return 6
    
    3 回复  |  直到 7 年前
        1
  •  1
  •   cнŝdk    7 年前

    这里没有封闭。

    你要做的是创造一个 function 它会返回另一个 功能 .

    在你的行里:

    const result = main();
    

    你把这个东西藏在里面 功能 A内 variable . 然后用两个参数调用它:

    result(2, 4);
    

    演示:

    请检查这个演示,以及内部函数如何存储在变量中,然后调用。

    function main() {
      return function child(num, num1) {
        console.log(num + num1);
      }
    }
    
    //Store inner function in a variable
    let innerFn = main();
    console.log(innerFn);
    console.log(typeof innerFn);
    
    
    //Then call this function
    innerFn();
    innerFn(10, 4);
        2
  •  1
  •   Quentin    7 年前

    以下两者之间没有实际区别(至少在您的问题范围内):

    function name (foo) {
    
    }
    

    function name () {
        var foo = arguments[0];
    }
    

    它只是创建一个函数范围的变量的两种方法。


    因此,它不会在主体中查找变量声明,如果找不到变量声明,也不会在参数中查找变量声明。它只是在函数范围内查找一个变量。

        3
  •  1
  •   Willem van der Veen    7 年前

    您的参数在您的函数范围内。当JS引擎遇到标识符时,它将首先查看当前正在执行的函数的作用域(参数和变量)。如果它在那里找不到这个变量,那么它将沿着作用域链向上移动,直到到达全局作用域为止。如果找不到它,它将抛出一个引用错误。

    例如:

    let foo = 1;
    let bar = 2;
    
    function test () {
      let foo = 5;
      
      console.log(foo, bar);
    }
    
    test();

    在本例中,foo被函数内部创建的新foo覆盖。JS引擎通过爬升范围链获得bar的值。

    闭包捕获创建函数时函数的环境,例如:

    function higher (value) {
      let el = value
      return () => console.log(el);
    }
    
    const first = higher(5)
    const second = higher(2);
    
    first();
    second();