zoukankan      html  css  js  c++  java
  • js之作用域链

    js采用的是词法作用域链,在代码书写阶段,作用域链就被定义了,所以 对于新手来说,要搞读懂js代码,首先就要弄清楚js的作用域链,下面看一份代码

    function test(a){
                var b = a+2;
                var bar = function(c){
                    console.log(a,b,c);
                }
                bar(b*a);
            }
            test(2);

    这个函数中 我们定义了一个test 函数,该函数中我们可以看出作用域链层层嵌套,首先是全局的,然后是test,然后是bar,在上下文执行栈中,全局执行环境会被放在栈底,而我们的test函数会第二个人入栈,然后发现里面嵌套了一个bar函数,又会将bar函数入栈

    我们用一个数组来比作执行上下文栈,那么上面代码可以写成

            var Esc = [];
            Esc.push(gloabContext);//首先全局上下文先压入栈底
            Esc.push(test); //其次是test的执行上下文
            Esc.push(bar);//最后入栈的是bar
            Esc.pop(bar);//然后bar 执行完之后就弹出 变量回收,闭包变量会存在
            Esc.pop(test);// test 弹出
            Esc.pop(gloabContext);// 浏览器或者也页面关闭时 全局执行环境清空

    上面就是一个静态作用域的执行流程,也就是说作用域只跟当前函数变量代码声明时有关,下面再看一个例子,

    var test = "global test";
            function foo(){
                var test = "local test";
                var bar = function(){
                    console.log(test);
                }
                bar();
            }
          foo() //输出 localtest

    上面输出的是local test ,因为当今入bar的执行上下文的时候,test 会在上一层作用域链foo的执行上下文中找到,也就是在作用域建立阶段,bar函数和test变量会绑定在foo的执行上下文环境中,我们再看一个例子

    var value = 1;
    
    function foo() {
        console.log(value);
    }
    
    function bar() {
        var value = 2;
        foo();
    }
    
    bar();//输出为1

    上面的代码,如果按照常规的思维,我们就会想到value 会在bar中找到,应该输出2,但这种想法是错的,因为作用域绑定在代码书写的时候就确定了,也就是说,当foo函数在全局上下文执行环境书写时,就跟全局value一块绑定了,所以当作用域链向上查找的时候

    就会找到全局value,而不是bar中的,所以,js中的作用域链是在书写代码时确定的,而不是在执行的时候确定的。

    我们再看一到题目,

    var test = "global test";
            function foo(){
                var test = "local test";
                var bar = function(){
                    console.log(test);
                }
                bar();
            }
          foo()
        var test1 = "global test1";
            function foo1(){
                var test1 = "local test1";
                var bar = function(){
                    console.log(test1);
                }
                return bar;
            }
            foo1()();

    这两段代码输出是一样的吗,如果一样,那么他们有不同点吗?

  • 相关阅读:
    Docker容器Centos容器安装openssh
    DEVOPS技术实践_15:使用Docker作为Jenkins的slave
    DEVOPS技术实践_14:使用docker部署jenkins
    oracle数据库创建实例
    Java 覆写初探
    Java super和this小结
    Java 继承学习
    Java 数据表映射
    Java 单向链表学习
    Java 继承初探
  • 原文地址:https://www.cnblogs.com/maoxiaodun/p/10071342.html
Copyright © 2011-2022 走看看