1.几个重要概念
(函数)有-->(执行环境)有-->(变量对象)形成-->(作用域链)
在一个页面中,第一次载入JS代码时创建一个全局执行环境,当调用一个JavaScript函数时,该函数就会进入相应的执行环境。如果又调用了另外一个函数(或者递归地调用同一个函数),则又会创建一个新的执行环境,并且在函数调用期间执行过程都处于该环境中。当调用的函数返回后,执行过程会返回原始执行环境。因而,运行中的JavaScript 代码就构成了一个执行环境栈。
在访问一个变量的时候,搜索过程从作用域链前端开始,一级一级向后回溯,知道找到变量标识符,否则会导致发生错误。
var color ="blue";
function changeColor(){
var anotherColor ="red";
function swapColors() {
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
}
swapColors();
}
changeColor();
上面代码展示了代码的作用域链:内层可以访问外层,外层无法访问内层:
每个函数都会有其执行环境,但要执行到一个函数的时候,就会将其环境推入到执行环境栈中,函数执行完毕之后,再将其弹出,返回之前的执行环境。而每个执行环境又有它的变量对象,里面保存着其中定义的函数和变量。当代码在一个环境中执行时,会形成一个变量对象的作用域链,当前环境的变量对象在最前端,其外部函数执行的变量对象在下一级,一直回溯到全局环境的变量对象。作用域链是保证了对执行环境有权访问的所有变量和函数的有序访问。当访问一个变量的时候,会从作用域的最前端开始搜索,逐级向上。
eg:
var num =1;
function showNum(){
var num =0;
return function(){
console.log(num);
}
}
var f = showNum();
f();//0
解析:最后打印出来的是0,showNum返回了一个匿名函数,并将其赋给了f,f()执行时,console.log(num),这时候就要从作用域链的前端开始搜索num,一级一级搜索的时候,先搜索到的是showNum函数执行环境变量对象中的num,所以搜索就停止了,因此,打印出的是0;如果console.log(this.num)那么情况就变了,因为f()在全局环境中执行,this指向window,所以会打印出1。
网友评论