执行环境是JavaScript中很重要的概念。执行环境定义了变量有权访问其它数据。
全局执行环境就是最外围的环境,在web浏览器中全局执行环境被认为是window对象,也就是说我们在全局环境中创建的变量和函数都是作为window对象的属性而存在的。
var a = "window对象的属性a"
function fun(){
console.log("所有在全局执行环境中创建的变量 函数都是作为window对象的属性而存在的")
}
window.fun();
console.log(window.a)
/*
所有在全局执行环境中创建的变量 函数都是作为window对象的属性而存在的
window对象的属性a
*/
当某个执行环境中的所有代码执行完毕后,保存在其中的所有变量和函数也会随即销毁(但是全局执行环境知道应用程序退出才会被销毁)
每个函数都有自己的执行环境。当执行到这个函数时这个函数的环境就会被推入环境栈中。而在函数执行之后,栈会把这个函数的执行环境弹出把控制权交还给之前的执行环境
当代码在一个环境中执行的时候会创建作用域链。作用域链的主要作用是保证对执行环境有权的访问的所有变量和函数的有序访问。作用域链的前端始终是当前执行环境下创建的变量
当某个执行环境要读取或写入一个标识符时,就会开始搜索这个标识符。搜索过程是从作用域的前端开始搜索,如果没有搜索到就向上逐级找符合名字匹配的标识符
(标识符用指的是 变量、函数、属性的名字,或者函数的参数)
var a = 1;
function fn1(){
function fn2(){
console.log(a);
}
function fn3(){
var a = 4;
fn2();
}
var a = 2;
return fn3
}
var fn = fn1();
fn();
//最后的输出结果2
上面这个示例最后的输出结果为2,这个例子对初学者来说并不友好。但是理解了上面这个例子就基本理解了作用域运行的规则。
首先 我们定义了函数fn1(),然后我们又在fn1内部创建了两个函数分别为fn2、fn3。然后再var a = 2;最后面return fn3,然后var fn = fn1();由于前面return fn3 所以调用fn()其实是在调用fn3
fn3()又调用了fn2()然后我们就会进入了fn()的作用域,这个时候我们就应该是从fn2的视角中寻找a,fn2内部并没有a所以他会向上级寻找也就是fn1,由于在变量始终在起当前作用域的最前端,所以最终结果为2
然后我们再看一个例子:
var color = "blue";
function changeColor(){
var anotherColor= "red";
function swapColor(){
var tempColor = anotherColor
anotherColor = color;
color = tempColor;
//这里可以访问到color、anotherColor和tempColor
}
//这里可以访问color和anotherColor,但不能访问tempColor
}
//这里只能访问color
changeColor();
这个例子表现就是 搜索标识符的时候只会沿着作用域上寻。
网友评论