zoukankan      html  css  js  c++  java
  • 浅谈js作用域与闭包

    作用域

    js的作用域有3种,分别是全局作用域,局部作用域,块级作用域(ES6新增)。

    全局作用域:在函数function以外定义的变量是全局变量,具有全局作用域,在任何地方都可以访问

            let a = 1;
            function x() {
                console.log(a);
            }
            x();    

    x()函数中并未声明变量a,但上面代码执行后会打印出1

    局部作用域:在函数function内定义的变量为局部变量,具有局部作用域,函数内部都可以访问

           function x() {
                let a = 1;
            }
            console.log(a);

    x()函数中定义了变量a,但在函数外部打印变量a会报错,提示a没有定义

    块级作用域:{}括号内定义的变量,具有块级作用域,{}以外无法访问,比如if判断和for循环中

          if (true) {
               let a = 1;
           }
           console.log(a);

    打印变量a会报错,提示a没有定义

    自由变量

    其实除上述3种变量外,还有一种特殊的变量叫自由变量。

    自由变量:一个变量在当前作用域中(也就是上述3种作用域)没有被定义,但却被使用了

           let a = 1;
           function x() {
               let b = 2;
               function y() {
                    console.log(a + b);
               }
               y();
           }
          x();

    x()函数执行后,结果为3,为什么y()中没有定义变量ab,但控制台却能打印出结果3呢?

    因为自由变量会像上级作用域一层一层的寻找,直至找到为止。所以当y()函数执行打印a+b时,

    虽然y()函数中没有定义变量a和b,但它会往上一级去寻找,这里的上一级是x()函数,但它只定义了变量b,

    因此会接着往上寻找,最后找到了x()函数外定义的全局变量a。

    注:如果全局作用域都没有找到,则会报错xxx is not defined

    闭包

    闭包可简单理解为作用域应用的2种特别情况:

    1. 函数作为返回值被返回

    2. 函数作为参数被传递

      

    上面2个示例执行代码后,a的值都为100, 你可能会有疑惑, 为什么a都是100呢?

    明明在函数执行之前已经重新定义了变量a的值,下面用大神总结的一句话就可迎刃而解

    总结:所有自由变量的查找是在函数定义的地方,向上级作用域一层一层往上查找,而不是在执行的地方

    红色框部分就是函数定义的地方,然后向上级作用域寻找,a的值为100

     

     

  • 相关阅读:
    并发编程概述
    学习笔记-ResNet网络
    学习笔记-反向传播算法
    学习笔记-canny边缘检测
    学习笔记-霍夫变换
    GitHub访问速度慢的一种优化方法
    C#开源定时回调库PETimer的使用
    C#开源网络通信库PESocket的使用
    XML在C#与Unity3D中的实战运用
    Unity本地持久化类Playerprefs使用详解
  • 原文地址:https://www.cnblogs.com/tu-0718/p/13686784.html
Copyright © 2011-2022 走看看