• 理解js中的自由变量以及作用域的进阶


     

    如果你不知道什么是作用域,建议你先看什么是作用域链,什么是原型链。这篇文章,因为这些内容都是有关联性的。

      什么是自由变量?

    如我在全局中定义了一个变量a,然后我在函数中使用了这个a,这个a就可以称之为自由变量,可以这样理解,凡是跨了自己的作用域的变量都叫自由变量。

    var a = "追梦子";
    function b(){
        console.log(a); //追梦子
    }
    b();

    上面的这段代码中的变量a就是一个自由变量,因为在函数b执行到console.log(a)的时候,发现在函数中找不到变量a,于是就往上一层中找,最后找到了全局变量a。

      作用域的进阶

    在我讲作用域链的时候说过如果有一个全局变量a,以及函数中也有一个变量a,那么只会作用函数中的那个变量a,都是有一种情况就显得比较复杂一些,我们一起来看看这段代码。

    复制代码
    var aa = 22;
    function a(){
        console.log(aa);
    }
    function b(fn){
        var aa = 11;
        fn();
    }
    b(a); //22
    复制代码

      最后打印的不是11而是22,为什么会这样呢?在我解释之前我建议你事先看一下js中的执行上下文,菜鸟入门基础。这一文,如果不了解js的执行顺序就比较难以理解,另外如果你看了我这几天的文章应该有种感觉,就是内容的关联性都特别强,这也是为什么很多js新手朋友不能够理解的地方。

      我们接着说为什么打印的是22,一起来分析一下这段代码。

    假如我们的代码是这样的

    var aa = 22;
    function a(){
        console.log(aa);
    }

    打印出的是22,我想大家应该没有意见,但是有一点我一定要提,那就是在创建这个函数的时候,这个函数的作用域就已经决定了,而是不是在调用的时候,这句话至管重要。

    有了这句话的基础是不是理解上面的那段代码就变得不值一提了?

      为了照护新手朋友我还是分析一下过程吧。

    首先我们创建了一个全局变量aa

    var aa = 22;

    接着我们创建了一个函数a

    function a(){
        console.log(aa);
    }

    这时js解析这个函数的时候,就已经决定了这个函数a的作用域,既如果在函数a中找不到变量aa那就会到全局变量中找,如果找到了就返回这个aa,如果找不到就报错。

    接着我们又创建了一个函数b

    function b(fn){
        var aa = 11;
        fn();
    }

    在函数b中我们定义了又重新定义了这个变量aa,虽然我们这个时候重新定义了变量aa,但是因为函数a的作用域在创建的时候已经决定了,所以在函数b中创建的那个变量aa以及和函数a里面的那个变量aa没有关系了。

    function b(fn){
        var aa = 11;
        fn();
    }
    b(a);

    我们把函数a传到了函数b中,并且当做函数b的形参,接着我们执行了这个被传进去的函数a,最后打印出来的就是22。

                 在创建这个函数的时候,这个函数的作用域就已经决定了,而是不是在调用的时候。

     
     
  • 相关阅读:
    LinkedBlockingQueue
    PriorityBlockingQueue
    js阻止事件冒泡
    java map常用的4种遍历方法
    JAVA jar 和 war 包的区别
    jquery 操作大全
    Java 使用new Thread和线程池的区别
    原生XMLHttpRequest
    socket 和 webscoket 的区别
    GET和POST请求的区别如下
  • 原文地址:https://www.cnblogs.com/zhangxiaolei521/p/5217916.html
Copyright © 2020-2023  润新知