JavaScript:作用域链 与 执行环境、词法环境

962 阅读2分钟

执行环境(Execution Context)

JSE生成执行环境有两个阶段,第一个创建阶段,一个执行阶段。
  Creation Phase:在内存中,为变量和函数开辟空间
  Execution Phase:一行行执行我们写下的代码,比如赋值

function b() {
	var myVar;
    console.log(myVar);//undefine
}
function a() {
	var myVar = 2;
    console.log(myVar);//2
	b();
}
var myVar = 1;
console.log(myVar);//1
a();
console.log(myVar);//1

变量环境(Variable Environment)

就像上图展示的这样,每个变量存在于自己的执行环境中,就是变量的环境。
同样是myVar,因为在不同的执行环境中,它们会被存在不同的内存里,所以并不会被覆盖。

词法环境(Lexically Environment)

一个变量/一个函数写在什么位置很重要。比如是直接定义在全局环境中,还是写在一个函数中。

语法解释器在编译之前会构建一颗语法树,解析层级关系。
一个变量/函数所处的位置,就是它的词法环境。

词法环境是静态的,在代码被执行之前就是可以知道的。执行环境反之,一定要执行时才能确定。

作用域链(Scope Chain)

function b() {

	console.log(myVar);//1
}
function a() {
	var myVar = 2;
	console.log(myVar);//2
	b();
}
var myVar = 1;
console.log(myVar);//1
a();
console.log(myVar);//1

同样的代码,但是函数b中没有声明变量myVar
在函数b中,输出的是1,而不是执行栈下面a()中声明的2。

因为在当前变量环境中没有找到的变量,会往外部环境中取寻找。

外部环境就是词法环境(Lexical Environment)。
简单来说,就是一个函数写在哪里。
函数a和函数b都写在全局环境中,它们的外部环境都是这个全局环境。

变量的指向是静态的,与之相对,this的指向是动态的,指向调用它的,最近的对象。