1

一、执行环境与作用域链

1.什么是执行环境

  • 执行环境定义了变量和函数的访问权限,决定了他们的各自行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有对象和函数都保存在这个对象里。
  • 全局环境是最外围的一个执行环境,在Web浏览器里全局执行环境被认为是window对象
  • 某个执行环境中所有代码执行完毕后该环境被销毁
  • 每个函数都自己的执行环境,当执行流进入一个函数时,函数的执行环境就会被压入环境栈中,函数执行完将环境弹出栈,把控制权返回之前的执行环境

2.作用域链及其作用

  • 代码在某个环境中执行时,会创建变量对象的一个作用域链
  • 通过作用域链保证对执行环境有权访问的所有变量和函数的有序访问
  • 作用域链的前端是当前执行的代码所在环境的变量对象

例:

var name1 = "11111";
function changeName(){
    var name2 = "22222";
    function swapName(){
        var tmpName = name1;
        name1 = name2;
        name2 = tmpName;
    }
    swapName();
}
changeName();

执行环境栈如下:从栈顶向栈底搜索变量
图片描述
上述代码中共有三个执行环境:全局环境、changeName局部环境和swapName局部环境;其中全局环境变量对象中有name1变量和changeName函数,changeName环境变量对象中有name2变量和swapName函数,swapName环境变量对象中有tmpName变量;全局环境和changeName局部环境都不能访问tmpName变量

二、块级作用域

ES6之前只有全局作用域和函数作用域

for(var i = 0; i < 5; i++){
    console.log(i);
}
console.log(i); //5

这里的i是在全局执行环境中的,就算for循环执行完全局执行环境中的变量也不会被销毁

function getSum(){
    var sum = 0;
    for(var i = 0; i < 5; i++){
        sum += i;
        console.log(sum);
    }
    console.log(i); //5
}
console.log(sum)//报错

上述代码中有两个执行环境,其中getSum执行环境中有变量sum、i,所以getSum可以访问到sum和i,当执行完getSum后该执行环境被销毁,全局环境中访问不到sum变量

function getSum(){
    sum = 0;
    for(var i = 0; i < 5; i++){
        sum += i;
        console.log(sum);
    }
    console.log(i); //5
}
console.log(sum)//10

上述代码中sum变量没有用var声明(不推荐这种做法),此时sum属于全局执行环境中,所以就算函数执行完毕sum依然存在

参考文章:JavaScript高级程序设计


SuRuiGit
264 声望23 粉丝