js作用域:函数作用域、全局作用域
作用域链:由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。
举个例子:
function demo(){
var a=10;
}
demo();
console.log(a);
解析
调用demo时开始创建demo的上下文执行环境,创建变量对象VO={a:undefined},创建作用域链:[VO(demo),VO(global)]。
执行demo上下文阶段,变量a赋值为10,执行结束,demo函数出栈,上下文被销毁。全局作用域中没有a对象,访问抛错。
VM80:5 Uncaught ReferenceError: a is not defined
at <anonymous>:5:13
闭包中的作用域
闭包:闭包是指有权访问另一个函数作用域中的变量函数;
闭包的功能:可以访问外部函数,维持函数作用域。
function demo2(){
var a=10;
function foo(){
return a;
}
return foo;
}
console.log(demo2()());
demo2()创建demo的上下文,创建变量对象VO={a:undefined,foo:<>},创建作用域链[VO(demo2) VO(global)];执行阶段a赋值10,返回foo函数。
demo()()即foo(),foo的作用域链为:[VO(foo),VO(demo2),VO(global)],foo函数可以访问函数demo2中的变量,也可以访问全局变量。foo函数执行return a;
demo2()执行后返回foo,此时demo已经执行结束了,其上下文应该被销毁,a应该被销毁。但是因为return foo的存在,导致foo函数的执行上下文被保留,而函数demo2中的执行上下文中包含了foo,所以demo的执行上下文不能被销毁,可以说闭包foo维持了demo2的作用域,a变量也就可以继续访问了。
网友评论