运行时的函数_融糖_前端开发者

  1. 一级函数 first-class functions

    1. 函数是一个对象

    2. 函数是一级函数函数可以

      1. 存储在变量中(函数表达式)

      2. 从一个函数返回

      3. 作为参数传递给另一个函数(回调)

    3. 高阶函数 higher-order function

      1. 返回另一个函数的函数 或 接受其他函数作为参数的函数 被称为高阶函数

        1. function alertThenReturn() {
              alert('Message 1!');
          
              return function () {
                  alert('Message 2!');
              };
          }
          
          const innerFunction = alertThenReturn();
          
          alertThenReturn();    // 显示 'Message 2!'
          innerFunction();        //显示 'Message 2!'
          alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
          
  2. 回调callback

  3. 作用域

    1. 词法作用域lexical scope和执行环境execution context

      1. 块作用域和函数作用域称为词法作用域

      2. 当一个函数被运行时,会创建一个新的运行时作用域。这个作用域表示该函数的上下文,就是可供该函数使用的一组变量。这就是运行时作用域,即执行环境。

    2. 执行环境包括:

      1. 函数的参数

      2. 函数内声明的本地变量

      3. 父函数作用域内声明的变量

      4. 全局变量

    3. 函数作用域 function scope

      1. 块级作用域 block scope

        1. ES6用let 和 const 关键字实现块级作用域

        2. var x = 10;      
          // 这里输出 x 为 10      
          {      
             let x = 2;      
          // 这里输出 x 为 2      
          }      
          // 这里输出 x 为 10
          
          1. const
            1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
            2. 作用域可以是全局或本地声明的块
          2. let
            1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
            2. 为什么使用let
              1. 像数学里的描述,let x be an arbitrary
          3. 暂存死区
            1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

            2. 该变量处在自顶部到初始化处理的暂存死区。

            3. 如以下代码中的ReferenceError

            4. function do_something() {
                console.log(bar); // undefined
                console.log(foo); // ReferenceError
                var bar = 1;
                let foo = 2;
              }
              
        3. 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

          1. var x = 10;    
            // 这里输出 x 为 10    
            {    
               var x = 2;    
            // 这里输出 x 为 2    
            }    
            // 这里输出 x 为 2
            
      2. 函数作用域

        1. 函数可以访问自己的所有变量和外部的所有全局变量
        2. var globalNumber = 5;
          
          function globalIncrementer() {
            const localNumber = 10;
          
            globalNumber += 1;
            return globalNumber;
          }
          
          console.log(globalIncrementer());    // 6
          
          console.log(globalIncrementer());    // 7
          
          console.log(globalIncrementer());    // 8
          
          console.log(localNumber);    // ReferenceError: localNumber is not defined 
          // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
          
      3. 作用域链 scope chain

          • 在访问变量时,js引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
        1. Window对象

          • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
      4. 变量阴影variable shadowing

        1. 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

          • var money = '¥';
            
            function myMoney() {
              var money = '$';
              console.log(money);
            }
            
            myMoney();
            console.log(money);
            
          • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
          • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
        2. 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  4. 闭包

    1. 词法作用域lexical scoping

      • ‘lexical’ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.词法作用域通过源代码(自己写的)中变量声明的位置来确定变量在此处否可用。
    2. 闭包 closure

      1. 词法环境(又一个坑)

        1. A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
          • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
        2. function makeFunc() {
              var name = 'count';
          
              function func2() {
                  console.log(name);
              }
              return func2;
          }
          
          var output = makeFunc();
          output();    // 'count'
          
        3. func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
          1. 因为js中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
            1. 闭包是由函数和创建该函数的词法环境组合而成。
            2. 在这里“词法环境”是指在js文件中编写的代码。
          2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
    3. 函数保留其作用域

      1. 标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。

      2. 当使用标识符时,作用域链将被检查,以检索标识符的值。作用域链对于函数访问代码中的标识符来说非常强大的工具。

  • 一级函数 first-class functions

    1. 函数是一个对象

    2. 函数是一级函数,函数可以

      1. 存储在变量中(函数表达式)

      2. 从一个函数返回

      3. 作为参数传递给另一个函数(回调)

    3. 高阶函数 higher-order function

      1. 返回另一个函数的函数 或 接受其他函数作为参数的函数 被称为高阶函数

        1. function alertThenReturn() {
              alert('Message 1!');
          
              return function () {
                  alert('Message 2!');
              };
          }
          
          const innerFunction = alertThenReturn();
          
          alertThenReturn();    // 显示 'Message 2!'
          innerFunction();        //显示 'Message 2!'
          alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
          
  • 一级函数 first-class functions

    1. 函数是一个对象

    2. 函数是一级函数,函数可以

      1. 存储在变量中(函数表达式)

      2. 从一个函数返回

      3. 作为参数传递给另一个函数(回调)

    3. 高阶函数 higher-order function

      1. 返回另一个函数的函数 或 接受其他函数作为参数的函数 被称为高阶函数

        1. function alertThenReturn() {
              alert('Message 1!');
          
              return function () {
                  alert('Message 2!');
              };
          }
          
          const innerFunction = alertThenReturn();
          
          alertThenReturn();    // 显示 'Message 2!'
          innerFunction();        //显示 'Message 2!'
          alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
          
  • 函数是一个对象

  • 函数是一个对象

  • 函数是一级函数,函数可以

    1. 存储在变量中(函数表达式)

    2. 从一个函数返回

    3. 作为参数传递给另一个函数(回调)

  • 函数是一级函数,函数可以

    1. 存储在变量中(函数表达式)

    2. 从一个函数返回

    3. 作为参数传递给另一个函数(回调)

  • 存储在变量中(函数表达式)

  • 存储在变量中(函数表达式)

  • 从一个函数返回

  • 从一个函数返回

  • 作为参数传递给另一个函数(回调)

  • 作为参数传递给另一个函数(回调)

  • 高阶函数 higher-order function

    1. 返回另一个函数的函数 或 接受其他函数作为参数的函数 被称为高阶函数

      1. function alertThenReturn() {
            alert('Message 1!');
        
            return function () {
                alert('Message 2!');
            };
        }
        
        const innerFunction = alertThenReturn();
        
        alertThenReturn();    // 显示 'Message 2!'
        innerFunction();        //显示 'Message 2!'
        alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
        
  • 高阶函数 higher-order function

    1. 返回另一个函数的函数 或 接受其他函数作为参数的函数 被称为高阶函数

      1. function alertThenReturn() {
            alert('Message 1!');
        
            return function () {
                alert('Message 2!');
            };
        }
        
        const innerFunction = alertThenReturn();
        
        alertThenReturn();    // 显示 'Message 2!'
        innerFunction();        //显示 'Message 2!'
        alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
        
  • 返回另一个函数的函数 或 接受其他函数作为参数的函数 被称为高阶函数

    1. function alertThenReturn() {
          alert('Message 1!');
      
          return function () {
              alert('Message 2!');
          };
      }
      
      const innerFunction = alertThenReturn();
      
      alertThenReturn();    // 显示 'Message 2!'
      innerFunction();        //显示 'Message 2!'
      alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
      
  • 返回另一个函数的函数 或 接受其他函数作为参数的函数 被称为高阶函数

    1. function alertThenReturn() {
          alert('Message 1!');
      
          return function () {
              alert('Message 2!');
          };
      }
      
      const innerFunction = alertThenReturn();
      
      alertThenReturn();    // 显示 'Message 2!'
      innerFunction();        //显示 'Message 2!'
      alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
      
  • function alertThenReturn() {
        alert('Message 1!');
    
        return function () {
            alert('Message 2!');
        };
    }
    
    const innerFunction = alertThenReturn();
    
    alertThenReturn();    // 显示 'Message 2!'
    innerFunction();        //显示 'Message 2!'
    alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
    
  • function alertThenReturn() {
        alert('Message 1!');
    
        return function () {
            alert('Message 2!');
        };
    }
    
    const innerFunction = alertThenReturn();
    
    alertThenReturn();    // 显示 'Message 2!'
    innerFunction();        //显示 'Message 2!'
    alertThenReturn()();    //显示 'Message 1!' 然后显示 'Message 2!'
    

    function alertThenReturn() {
    alert('Message 1!');

    return function () {
    alert('Message 2!');
    };
    }

    const innerFunction = alertThenReturn();

    alertThenReturn(); // 显示 'Message 2!'
    innerFunction(); //显示 'Message 2!'
    alertThenReturn()(); //显示 'Message 1!' 然后显示 'Message 2!'

  • 回调callback

  • 回调callback

  • 作用域

    1. 词法作用域lexical scope和执行环境execution context

      1. 块作用域和函数作用域称为词法作用域

      2. 当一个函数被运行时,会创建一个新的运行时作用域。这个作用域表示该函数的上下文,就是可供该函数使用的一组变量。这就是运行时作用域,即执行环境。

    2. 执行环境包括:

      1. 函数的参数

      2. 函数内声明的本地变量

      3. 父函数作用域内声明的变量

      4. 全局变量

    3. 函数作用域 function scope

      1. 块级作用域 block scope

        1. ES6用let 和 const 关键字实现块级作用域

        2. var x = 10;      
          // 这里输出 x 为 10      
          {      
             let x = 2;      
          // 这里输出 x 为 2      
          }      
          // 这里输出 x 为 10
          
          1. const
            1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
            2. 作用域可以是全局或本地声明的块
          2. let
            1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
            2. 为什么使用let
              1. 像数学里的描述,let x be an arbitrary
          3. 暂存死区
            1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

            2. 该变量处在自顶部到初始化处理的暂存死区。

            3. 如以下代码中的ReferenceError

            4. function do_something() {
                console.log(bar); // undefined
                console.log(foo); // ReferenceError
                var bar = 1;
                let foo = 2;
              }
              
        3. 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

          1. var x = 10;    
            // 这里输出 x 为 10    
            {    
               var x = 2;    
            // 这里输出 x 为 2    
            }    
            // 这里输出 x 为 2
            
      2. 函数作用域

        1. 函数可以访问自己的所有变量和外部的所有全局变量
        2. var globalNumber = 5;
          
          function globalIncrementer() {
            const localNumber = 10;
          
            globalNumber += 1;
            return globalNumber;
          }
          
          console.log(globalIncrementer());    // 6
          
          console.log(globalIncrementer());    // 7
          
          console.log(globalIncrementer());    // 8
          
          console.log(localNumber);    // ReferenceError: localNumber is not defined 
          // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
          
      3. 作用域链 scope chain

          • 在访问变量时,js引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
        1. Window对象

          • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
      4. 变量阴影variable shadowing

        1. 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

          • var money = '¥';
            
            function myMoney() {
              var money = '$';
              console.log(money);
            }
            
            myMoney();
            console.log(money);
            
          • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
          • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
        2. 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  • 作用域

    1. 词法作用域lexical scope和执行环境execution context

      1. 块作用域和函数作用域称为词法作用域

      2. 当一个函数被运行时,会创建一个新的运行时作用域。这个作用域表示该函数的上下文,就是可供该函数使用的一组变量。这就是运行时作用域,即执行环境。

    2. 执行环境包括:

      1. 函数的参数

      2. 函数内声明的本地变量

      3. 父函数作用域内声明的变量

      4. 全局变量

    3. 函数作用域 function scope

      1. 块级作用域 block scope

        1. ES6用let 和 const 关键字实现块级作用域

        2. var x = 10;      
          // 这里输出 x 为 10      
          {      
             let x = 2;      
          // 这里输出 x 为 2      
          }      
          // 这里输出 x 为 10
          
          1. const
            1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
            2. 作用域可以是全局或本地声明的块
          2. let
            1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
            2. 为什么使用let
              1. 像数学里的描述,let x be an arbitrary
          3. 暂存死区
            1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

            2. 该变量处在自顶部到初始化处理的暂存死区。

            3. 如以下代码中的ReferenceError

            4. function do_something() {
                console.log(bar); // undefined
                console.log(foo); // ReferenceError
                var bar = 1;
                let foo = 2;
              }
              
        3. 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

          1. var x = 10;    
            // 这里输出 x 为 10    
            {    
               var x = 2;    
            // 这里输出 x 为 2    
            }    
            // 这里输出 x 为 2
            
      2. 函数作用域

        1. 函数可以访问自己的所有变量和外部的所有全局变量
        2. var globalNumber = 5;
          
          function globalIncrementer() {
            const localNumber = 10;
          
            globalNumber += 1;
            return globalNumber;
          }
          
          console.log(globalIncrementer());    // 6
          
          console.log(globalIncrementer());    // 7
          
          console.log(globalIncrementer());    // 8
          
          console.log(localNumber);    // ReferenceError: localNumber is not defined 
          // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
          
      3. 作用域链 scope chain

          • 在访问变量时,js引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
        1. Window对象

          • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
      4. 变量阴影variable shadowing

        1. 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

          • var money = '¥';
            
            function myMoney() {
              var money = '$';
              console.log(money);
            }
            
            myMoney();
            console.log(money);
            
          • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
          • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
        2. 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  • 词法作用域lexical scope和执行环境execution context

    1. 块作用域和函数作用域称为词法作用域

    2. 当一个函数被运行时,会创建一个新的运行时作用域。这个作用域表示该函数的上下文,就是可供该函数使用的一组变量。这就是运行时作用域,即执行环境。

  • 词法作用域lexical scope和执行环境execution context

    1. 块作用域和函数作用域称为词法作用域

    2. 当一个函数被运行时,会创建一个新的运行时作用域。这个作用域表示该函数的上下文,就是可供该函数使用的一组变量。这就是运行时作用域,即执行环境。

  • 块作用域和函数作用域称为词法作用域

  • 块作用域和函数作用域称为词法作用域

  • 当一个函数被运行时,会创建一个新的运行时作用域。这个作用域表示该函数的上下文,就是可供该函数使用的一组变量。这就是运行时作用域,即执行环境。

  • 当一个函数被运行时,会创建一个新的运行时作用域。这个作用域表示该函数的上下文,就是可供该函数使用的一组变量。这就是运行时作用域,即执行环境。

  • 执行环境包括:

    1. 函数的参数

    2. 函数内声明的本地变量

    3. 父函数作用域内声明的变量

    4. 全局变量

  • 执行环境包括:

    1. 函数的参数

    2. 函数内声明的本地变量

    3. 父函数作用域内声明的变量

    4. 全局变量

  • 函数的参数

  • 函数的参数

  • 函数内声明的本地变量

  • 函数内声明的本地变量

  • 父函数作用域内声明的变量

  • 父函数作用域内声明的变量

  • 全局变量

  • 全局变量

  • 函数作用域 function scope

    1. 块级作用域 block scope

      1. ES6用let 和 const 关键字实现块级作用域

      2. var x = 10;      
        // 这里输出 x 为 10      
        {      
           let x = 2;      
        // 这里输出 x 为 2      
        }      
        // 这里输出 x 为 10
        
        1. const
          1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
          2. 作用域可以是全局或本地声明的块
        2. let
          1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
          2. 为什么使用let
            1. 像数学里的描述,let x be an arbitrary
        3. 暂存死区
          1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

          2. 该变量处在自顶部到初始化处理的暂存死区。

          3. 如以下代码中的ReferenceError

          4. function do_something() {
              console.log(bar); // undefined
              console.log(foo); // ReferenceError
              var bar = 1;
              let foo = 2;
            }
            
      3. 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

        1. var x = 10;    
          // 这里输出 x 为 10    
          {    
             var x = 2;    
          // 这里输出 x 为 2    
          }    
          // 这里输出 x 为 2
          
    2. 函数作用域

      1. 函数可以访问自己的所有变量和外部的所有全局变量
      2. var globalNumber = 5;
        
        function globalIncrementer() {
          const localNumber = 10;
        
          globalNumber += 1;
          return globalNumber;
        }
        
        console.log(globalIncrementer());    // 6
        
        console.log(globalIncrementer());    // 7
        
        console.log(globalIncrementer());    // 8
        
        console.log(localNumber);    // ReferenceError: localNumber is not defined 
        // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
        
    3. 作用域链 scope chain

        • 在访问变量时,js引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
      1. Window对象

        • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
    4. 变量阴影variable shadowing

      1. 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

        • var money = '¥';
          
          function myMoney() {
            var money = '$';
            console.log(money);
          }
          
          myMoney();
          console.log(money);
          
        • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
        • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
      2. 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  • 函数作用域 function scope

    1. 块级作用域 block scope

      1. ES6用let 和 const 关键字实现块级作用域

      2. var x = 10;      
        // 这里输出 x 为 10      
        {      
           let x = 2;      
        // 这里输出 x 为 2      
        }      
        // 这里输出 x 为 10
        
        1. const
          1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
          2. 作用域可以是全局或本地声明的块
        2. let
          1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
          2. 为什么使用let
            1. 像数学里的描述,let x be an arbitrary
        3. 暂存死区
          1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

          2. 该变量处在自顶部到初始化处理的暂存死区。

          3. 如以下代码中的ReferenceError

          4. function do_something() {
              console.log(bar); // undefined
              console.log(foo); // ReferenceError
              var bar = 1;
              let foo = 2;
            }
            
      3. 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

        1. var x = 10;    
          // 这里输出 x 为 10    
          {    
             var x = 2;    
          // 这里输出 x 为 2    
          }    
          // 这里输出 x 为 2
          
    2. 函数作用域

      1. 函数可以访问自己的所有变量和外部的所有全局变量
      2. var globalNumber = 5;
        
        function globalIncrementer() {
          const localNumber = 10;
        
          globalNumber += 1;
          return globalNumber;
        }
        
        console.log(globalIncrementer());    // 6
        
        console.log(globalIncrementer());    // 7
        
        console.log(globalIncrementer());    // 8
        
        console.log(localNumber);    // ReferenceError: localNumber is not defined 
        // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
        
    3. 作用域链 scope chain

        • 在访问变量时,js引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
      1. Window对象

        • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
    4. 变量阴影variable shadowing

      1. 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

        • var money = '¥';
          
          function myMoney() {
            var money = '$';
            console.log(money);
          }
          
          myMoney();
          console.log(money);
          
        • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
        • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
      2. 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  • 块级作用域 block scope

    1. ES6用let 和 const 关键字实现块级作用域

    2. var x = 10;      
      // 这里输出 x 为 10      
      {      
         let x = 2;      
      // 这里输出 x 为 2      
      }      
      // 这里输出 x 为 10
      
      1. const
        1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
        2. 作用域可以是全局或本地声明的块
      2. let
        1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
        2. 为什么使用let
          1. 像数学里的描述,let x be an arbitrary
      3. 暂存死区
        1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

        2. 该变量处在自顶部到初始化处理的暂存死区。

        3. 如以下代码中的ReferenceError

        4. function do_something() {
            console.log(bar); // undefined
            console.log(foo); // ReferenceError
            var bar = 1;
            let foo = 2;
          }
          
    3. 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

      1. var x = 10;    
        // 这里输出 x 为 10    
        {    
           var x = 2;    
        // 这里输出 x 为 2    
        }    
        // 这里输出 x 为 2
        
  • 块级作用域 block scope

    1. ES6用let 和 const 关键字实现块级作用域

    2. var x = 10;      
      // 这里输出 x 为 10      
      {      
         let x = 2;      
      // 这里输出 x 为 2      
      }      
      // 这里输出 x 为 10
      
      1. const
        1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
        2. 作用域可以是全局或本地声明的块
      2. let
        1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
        2. 为什么使用let
          1. 像数学里的描述,let x be an arbitrary
      3. 暂存死区
        1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

        2. 该变量处在自顶部到初始化处理的暂存死区。

        3. 如以下代码中的ReferenceError

        4. function do_something() {
            console.log(bar); // undefined
            console.log(foo); // ReferenceError
            var bar = 1;
            let foo = 2;
          }
          
    3. 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

      1. var x = 10;    
        // 这里输出 x 为 10    
        {    
           var x = 2;    
        // 这里输出 x 为 2    
        }    
        // 这里输出 x 为 2
        
  • ES6用let 和 const 关键字实现块级作用域

  • ES6用let 和 const 关键字实现块级作用域

  • var x = 10;      
    // 这里输出 x 为 10      
    {      
       let x = 2;      
    // 这里输出 x 为 2      
    }      
    // 这里输出 x 为 10
    
    1. const
      1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
      2. 作用域可以是全局或本地声明的块
    2. let
      1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
      2. 为什么使用let
        1. 像数学里的描述,let x be an arbitrary
    3. 暂存死区
      1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

      2. 该变量处在自顶部到初始化处理的暂存死区。

      3. 如以下代码中的ReferenceError

      4. function do_something() {
          console.log(bar); // undefined
          console.log(foo); // ReferenceError
          var bar = 1;
          let foo = 2;
        }
        
  • var x = 10;      
    // 这里输出 x 为 10      
    {      
       let x = 2;      
    // 这里输出 x 为 2      
    }      
    // 这里输出 x 为 10
    

    var x = 10;
    // 这里输出 x 为 10
    {
    let x = 2;
    // 这里输出 x 为 2
    }
    // 这里输出 x 为 10

    1. const
      1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
      2. 作用域可以是全局或本地声明的块
    2. let
      1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
      2. 为什么使用let
        1. 像数学里的描述,let x be an arbitrary
    3. 暂存死区
      1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

      2. 该变量处在自顶部到初始化处理的暂存死区。

      3. 如以下代码中的ReferenceError

      4. function do_something() {
          console.log(bar); // undefined
          console.log(foo); // ReferenceError
          var bar = 1;
          let foo = 2;
        }
        
  • const
    1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
    2. 作用域可以是全局或本地声明的块
  • const
    1. 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
    2. 作用域可以是全局或本地声明的块
  • 此声明创建一个常量。常量的值不能通过重新赋值来改变,并且不能重新声明
  • 作用域可以是全局或本地声明的块
  • let
    1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
    2. 为什么使用let
      1. 像数学里的描述,let x be an arbitrary
  • let
    1. 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
    2. 为什么使用let
      1. 像数学里的描述,let x be an arbitrary
  • 声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
  • 为什么使用let
    1. 像数学里的描述,let x be an arbitrary
    1. 像数学里的描述,let x be an arbitrary
  • 像数学里的描述,let x be an arbitrary
  • 暂存死区
    1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

    2. 该变量处在自顶部到初始化处理的暂存死区。

    3. 如以下代码中的ReferenceError

    4. function do_something() {
        console.log(bar); // undefined
        console.log(foo); // ReferenceError
        var bar = 1;
        let foo = 2;
      }
      
  • 暂存死区
    1. 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

    2. 该变量处在自顶部到初始化处理的暂存死区。

    3. 如以下代码中的ReferenceError

    4. function do_something() {
        console.log(bar); // undefined
        console.log(foo); // ReferenceError
        var bar = 1;
        let foo = 2;
      }
      
  • 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

  • 通过let声明的变量直到他们的定义被执行时才初始化,在初始化前访问该变量会导致ReferenceError.

  • 该变量处在自顶部到初始化处理的暂存死区。

  • 该变量处在自顶部到初始化处理的暂存死区。

  • 如以下代码中的ReferenceError

  • 如以下代码中的ReferenceError

    如以下代码中的ReferenceErrorReferenceError

  • function do_something() {
      console.log(bar); // undefined
      console.log(foo); // ReferenceError
      var bar = 1;
      let foo = 2;
    }
    
  • function do_something() {
      console.log(bar); // undefined
      console.log(foo); // ReferenceError
      var bar = 1;
      let foo = 2;
    }
    

    function do_something() {
    console.log(bar); // undefined
    console.log(foo); // ReferenceError
    var bar = 1;
    let foo = 2;
    }

  • 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

    1. var x = 10;    
      // 这里输出 x 为 10    
      {    
         var x = 2;    
      // 这里输出 x 为 2    
      }    
      // 这里输出 x 为 2
      
  • 用var关键字声明的变量不具备块级作用域的特性,在{ }外依然能被访问到

    1. var x = 10;    
      // 这里输出 x 为 10    
      {    
         var x = 2;    
      // 这里输出 x 为 2    
      }    
      // 这里输出 x 为 2
      
  • var x = 10;    
    // 这里输出 x 为 10    
    {    
       var x = 2;    
    // 这里输出 x 为 2    
    }    
    // 这里输出 x 为 2
    
  • var x = 10;    
    // 这里输出 x 为 10    
    {    
       var x = 2;    
    // 这里输出 x 为 2    
    }    
    // 这里输出 x 为 2
    

    var x = 10;
    // 这里输出 x 为 10
    {
    var x = 2;
    // 这里输出 x 为 2
    }
    // 这里输出 x 为 2

  • 函数作用域

    1. 函数可以访问自己的所有变量和外部的所有全局变量
    2. var globalNumber = 5;
      
      function globalIncrementer() {
        const localNumber = 10;
      
        globalNumber += 1;
        return globalNumber;
      }
      
      console.log(globalIncrementer());    // 6
      
      console.log(globalIncrementer());    // 7
      
      console.log(globalIncrementer());    // 8
      
      console.log(localNumber);    // ReferenceError: localNumber is not defined 
      // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
      
  • 函数作用域

    1. 函数可以访问自己的所有变量和外部的所有全局变量
    2. var globalNumber = 5;
      
      function globalIncrementer() {
        const localNumber = 10;
      
        globalNumber += 1;
        return globalNumber;
      }
      
      console.log(globalIncrementer());    // 6
      
      console.log(globalIncrementer());    // 7
      
      console.log(globalIncrementer());    // 8
      
      console.log(localNumber);    // ReferenceError: localNumber is not defined 
      // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
      
  • 函数可以访问自己的所有变量和外部的所有全局变量
  • var globalNumber = 5;
    
    function globalIncrementer() {
      const localNumber = 10;
    
      globalNumber += 1;
      return globalNumber;
    }
    
    console.log(globalIncrementer());    // 6
    
    console.log(globalIncrementer());    // 7
    
    console.log(globalIncrementer());    // 8
    
    console.log(localNumber);    // ReferenceError: localNumber is not defined 
    // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
    
  • var globalNumber = 5;
    
    function globalIncrementer() {
      const localNumber = 10;
    
      globalNumber += 1;
      return globalNumber;
    }
    
    console.log(globalIncrementer());    // 6
    
    console.log(globalIncrementer());    // 7
    
    console.log(globalIncrementer());    // 8
    
    console.log(localNumber);    // ReferenceError: localNumber is not defined 
    // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域
    

    var globalNumber = 5;

    function globalIncrementer() {
    const localNumber = 10;

    globalNumber += 1;
    return globalNumber;
    }

    console.log(globalIncrementer()); // 6

    console.log(globalIncrementer()); // 7

    console.log(globalIncrementer()); // 8

    console.log(localNumber); // ReferenceError: localNumber is not defined
    // 这里localNumber在log函数的外部,因为无法取到localNumber的值,const定义的块级作用域

  • 作用域链 scope chain

      • 在访问变量时,js引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
    1. Window对象

      • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
  • 作用域链 scope chain

      • 在访问变量时,JS引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
    1. Window对象

      • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
    • 在访问变量时,JS引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
    • 在访问变量时,JS引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
  • 在访问变量时,JS引擎将遍历作用域链(查找变量的顺序是线性的),首先查看最内层,然后查看外层作用域,最后在必要时到达全局作用域。
  • 作用域链

  • Window对象

    • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
  • Window对象

    • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
  • 声明的任何全局变量都是作为window对象(全局对象)的属性被访问的,它表示作用域链的最外层。
  • 变量阴影variable shadowing

    1. 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

      • var money = '¥';
        
        function myMoney() {
          var money = '$';
          console.log(money);
        }
        
        myMoney();
        console.log(money);
        
      • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
      • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
    2. 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  • 变量阴影variable shadowing

    1. 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

      • var money = '¥';
        
        function myMoney() {
          var money = '$';
          console.log(money);
        }
        
        myMoney();
        console.log(money);
        
      • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
      • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
    2. 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  • 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

    • var money = '¥';
      
      function myMoney() {
        var money = '$';
        console.log(money);
      }
      
      myMoney();
      console.log(money);
      
    • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
    • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
  • 创建的变量与作用域中的另一个变量具有相同名称时,局部作用域的变量会shadow外部作用域中的变量

    • var money = '¥';
      
      function myMoney() {
        var money = '$';
        console.log(money);
      }
      
      myMoney();
      console.log(money);
      
    • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
    • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
  • var money = '¥';
    
    function myMoney() {
      var money = '$';
      console.log(money);
    }
    
    myMoney();
    console.log(money);
    
  • var money = '¥';
    
    function myMoney() {
      var money = '$';
      console.log(money);
    }
    
    myMoney();
    console.log(money);
    

    var money = '¥';

    function myMoney() {
    var money = '$';
    console.log(money);
    }

    myMoney();
    console.log(money);

  • 指向’$’的变量是在函数内部声明的,将shadow位于外部作用域的同名变量,即指向’¥’的全局变量
  • 如果函数内部的没有变量声明,只有一个赋值,则会造成scope shadowing
  • 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

  • 在不同执行环境中的变量之间有任何重名重叠,会通过从内部作用域到外部作用域遍历作用域链来解决。

    遍历作用域

  • 闭包

    1. 词法作用域lexical scoping

      • ‘lexical’ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.词法作用域通过源代码(自己写的)中变量声明的位置来确定变量在此处否可用。
    2. 闭包 closure

      1. 词法环境(又一个坑)

        1. A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
          • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
        2. function makeFunc() {
              var name = 'count';
          
              function func2() {
                  console.log(name);
              }
              return func2;
          }
          
          var output = makeFunc();
          output();    // 'count'
          
        3. func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
          1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
            1. 闭包是由函数和创建该函数的词法环境组合而成。
            2. 在这里“词法环境”是指在JS文件中编写的代码。
          2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
    3. 函数保留其作用域

      1. 标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。

      2. 当使用标识符时,作用域链将被检查,以检索标识符的值。作用域链对于函数访问代码中的标识符来说非常强大的工具。

  • 闭包

    1. 词法作用域lexical scoping

      • ‘lexical’ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.词法作用域通过源代码(自己写的)中变量声明的位置来确定变量在此处否可用。
    2. 闭包 closure

      1. 词法环境(又一个坑)

        1. A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
          • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
        2. function makeFunc() {
              var name = 'count';
          
              function func2() {
                  console.log(name);
              }
              return func2;
          }
          
          var output = makeFunc();
          output();    // 'count'
          
        3. func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
          1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
            1. 闭包是由函数和创建该函数的词法环境组合而成。
            2. 在这里“词法环境”是指在JS文件中编写的代码。
          2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
    3. 函数保留其作用域

      1. 标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。

      2. 当使用标识符时,作用域链将被检查,以检索标识符的值。作用域链对于函数访问代码中的标识符来说非常强大的工具。

  • 词法作用域lexical scoping

    • ‘lexical’ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.词法作用域通过源代码(自己写的)中变量声明的位置来确定变量在此处否可用。
  • 词法作用域lexical scoping

    • ‘lexical’ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.词法作用域通过源代码(自己写的)中变量声明的位置来确定变量在此处否可用。
  • ‘lexical’ refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.词法作用域通过源代码(自己写的)中变量声明的位置来确定变量在此处否可用。
  • 闭包 closure

    1. 词法环境(又一个坑)

      1. A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
        • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
      2. function makeFunc() {
            var name = 'count';
        
            function func2() {
                console.log(name);
            }
            return func2;
        }
        
        var output = makeFunc();
        output();    // 'count'
        
      3. func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
        1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
          1. 闭包是由函数和创建该函数的词法环境组合而成。
          2. 在这里“词法环境”是指在JS文件中编写的代码。
        2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
  • 闭包 closure

    1. 词法环境(又一个坑)

      1. A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
        • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
      2. function makeFunc() {
            var name = 'count';
        
            function func2() {
                console.log(name);
            }
            return func2;
        }
        
        var output = makeFunc();
        output();    // 'count'
        
      3. func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
        1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
          1. 闭包是由函数和创建该函数的词法环境组合而成。
          2. 在这里“词法环境”是指在JS文件中编写的代码。
        2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
  • 词法环境(又一个坑)

    1. A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
      • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
    2. function makeFunc() {
          var name = 'count';
      
          function func2() {
              console.log(name);
          }
          return func2;
      }
      
      var output = makeFunc();
      output();    // 'count'
      
    3. func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
      1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
        1. 闭包是由函数和创建该函数的词法环境组合而成。
        2. 在这里“词法环境”是指在JS文件中编写的代码。
      2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
  • 词法环境(又一个坑)

    词法环境(又一个坑)

    1. A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
      • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
    2. function makeFunc() {
          var name = 'count';
      
          function func2() {
              console.log(name);
          }
          return func2;
      }
      
      var output = makeFunc();
      output();    // 'count'
      
    3. func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
      1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
        1. 闭包是由函数和创建该函数的词法环境组合而成。
        2. 在这里“词法环境”是指在JS文件中编写的代码。
      2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
  • A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。
    • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
  • A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upom the lexical nesting structure of ES code. 词法环境是一个规范类型,是标识符与特定变量和函数基于ES代码的词法嵌套结构的关联。

    • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
  • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。
  • 一个词法环境由环境记录和可能为空的外部词法环境引用组成。

  • function makeFunc() {
        var name = 'count';
    
        function func2() {
            console.log(name);
        }
        return func2;
    }
    
    var output = makeFunc();
    output();    // 'count'
    
  • function makeFunc() {
        var name = 'count';
    
        function func2() {
            console.log(name);
        }
        return func2;
    }
    
    var output = makeFunc();
    output();    // 'count'
    

    function makeFunc() {
    var name = 'count';

    function func2() {
    console.log(name);
    }
    return func2;
    }

    var output = makeFunc();
    output(); // 'count'

  • func2还未执行,被func1返回。一般来说,该段代码不能正常运行,因为局部变量name在func1执行完毕后,name将不能再被访问。但是,Why it works?
    1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
      1. 闭包是由函数和创建该函数的词法环境组合而成。
      2. 在这里“词法环境”是指在JS文件中编写的代码。
    2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
    1. 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
      1. 闭包是由函数和创建该函数的词法环境组合而成。
      2. 在这里“词法环境”是指在JS文件中编写的代码。
    2. output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
  • 因为JS中的函数会形成闭包。函数保留对其作用域的访问的这个过程被称为闭包。
    1. 闭包是由函数和创建该函数的词法环境组合而成。
    2. 在这里“词法环境”是指在JS文件中编写的代码。
  • 函数保留对其作用域的访问的这个过程被称为闭包。

    1. 闭包是由函数和创建该函数的词法环境组合而成。
    2. 在这里“词法环境”是指在JS文件中编写的代码。
  • 闭包是由函数和创建该函数的词法环境组合而成。
  • 闭包是由函数和创建该函数的词法环境组合而成。

  • 在这里“词法环境”是指在JS文件中编写的代码。
  • output是func2函数实例的引用,而func2实例仍可访问其词法作用域中的变量,即可以访问name.
  • 实例

  • 函数保留其作用域

    1. 标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。

    2. 当使用标识符时,作用域链将被检查,以检索标识符的值。作用域链对于函数访问代码中的标识符来说非常强大的工具。

  • 函数保留其作用域

    1. 标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。

    2. 当使用标识符时,作用域链将被检查,以检索标识符的值。作用域链对于函数访问代码中的标识符来说非常强大的工具。

  • 标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。

  • 标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。

    标识符

  • 当使用标识符时,作用域链将被检查,以检索标识符的值。作用域链对于函数访问代码中的标识符来说非常强大的工具。

  • 当使用标识符时,作用域链将被检查,以检索标识符的值。作用域链对于函数访问代码中的标识符来说非常强大的工具。

    » 本文来自:前端开发者 » 《运行时的函数_融糖_前端开发者》
    » 本文链接地址:https://www.rokub.com/73343.html
    » 您也可以订阅本站:https://www.rokub.com
    赞(0)
    64K

    评论 抢沙发

    评论前必须登录!