<script>
function a(){
var x=1;
window.b=function(){
alert(x);
}
}
a();
b();//弹出1
</script>
window.b=function(){ // 代码 }
这相当于定义了一个全局函数吧,请问为什么全局函数(window.b)可以访问其他函数(函数a)内部的变量(变量x)呢?
看了两个朋友的回答后,我知道自己的疑问具体是什么了:
window.b是定义一个全局函数,那么window.b和函数a应该都是全局环境下的函数了。
就好像function f1() { // 代码} 和 function f2() { // 代码}一样,都是全局环境下的、同一级别的函数,不存在父函数与子函数的嵌套了。
既然window.b和函数a,两者是同一个级别的函数,为什么window.b还可以访问函数a的局部变量呢?
因为JavaScript的作用域是lexical scope。什么是lexical scope(词法作用域or静态作用域)?
也就是说,函数的lexical scope是却决于你在哪里定义这个函数的。
那么好,你的
b
是定义在a
里面的。所以作用域链是这样的:global scope <- a's scope -> b's scope
b
要引用x
的时候,首先在自己的作用域找,找不到。a
的作用域就找到了。就算
a
和window.b
是同一个级别的函数,但是两者被定义的地方不同,前者被你定义在global scope,后者则定义在
a
的scope。而lexical scope又是却决于你是在哪里定义函数的。不如,写成这样,或许可以更好理解。
b()
是闭包,通过b()
在a()
外访问a()
中的变量是闭包特性之一。闭包?
b()函数是个匿名函数表达式,并且是该表达式赋值给了b全局变量,这种情况下b()其实就是作为全局环境的变量对象window的方法创建的,在b()中会有个作用域链,它可以向上访问来自包含环境a()的所有的变量或函数,其实这也是闭包的特性之一:函数可以访问另一个函数的值,也就是函数套函数,子函数可访问父级函数的所有值,粗浅理解,有什么不对的地方恳求指正- -
<script> var b; function a(){ var x=1; b=function(){ alert(x); } } a(); b();//弹出1 </script>
定义是在全局,但是b在a的作用域中被赋值,可以使用a的局部变量