4 / 5 词法作用域和动态作用域

前面的话

前端日问 ,巩固基础,不打烊!!!

解答

作用域:指程序源代码中定义变量的区域它规定了如何去查找变量

JavaScript中采用的是词法作用域,也就是静态作用域。因为JavaScript采用的是词法作用域,所以函数的作用域在函数定义的时候就决定了。

var value = 1;

function foo() {
    console.log(value);
}

function bar() {
    var value = 2;
    foo();
}

bar(); // ? 

上面的结果为:1

  • 原因: 执行foo函数是,先看foo函数内部是否有局部变量value, 如果没有就根据其定义的位置,查找上层的代码,value为1.
  • 如果采用动态作用域,先出foo函数内部查看是否有局部的变量value,如果没有,就从调用它的函数bar的中找,结果为2。(bash采用的是动态作用域)

题目

// 代码一:
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
checkscope();
// 代码二:
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()();
  • 两份代码都是:local scope,因为函数f是在checkscope函数中定义的,所以查找变量scope时,先在函数f内部找,没有的话,就到其定义的位置中去查找,即checkscope内部查找,为local scope
  • 两份代码的区别是啥呢? 是执行上下文栈 的不同:
    • 代码一: 先执行checkscope函数:ECStack.push(<checkscope> functionContext);;而checkscope函数里面又执行了f函数:ECStack.push(<f> functionContext);;执行完毕后,f的执行上下文出栈:ECStack.pop(); ; 接着checkscope的执行上下文出栈:ECStack.pop();
    • 代码二:先执行checkscope函数:ECStack.push(<checkscope> functionContext);;执行完毕后,出栈:ECStack.pop();; 接着执行f函数:ECStack.push(<f> functionContext);; 执行完毕后,出栈:ECStack.pop();

注意:全局执行上下文这里没有写出,在代码开始时,就会被推入栈中,且是唯一的。

参考文章:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章