一、实行环境与作用域链
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高等程序设计