部门技术交流中学习了这篇文章:
的确是一篇很不错的文章。回来再琢磨了一下,觉得有两点是要重点注意的:
1. javascript中没有block级作用域,但有函数级作用域
2. JS引擎执行函数的时候,会首先根据函数体内的变量声明(注意不是定义)分配变量的内存资源,不管这些变量声明的位置。而当遇到和函数作用域外名称相同的变量,中函数内部会覆盖掉函数作用域外的变量
对于第一点,引用原文的示例代码做一点点改动:
<script type="text/javascript"> function rainman(){ // rainman函数体内存在三个局部变量 i j k var i = 0; if ( 1 ) { var j = 0; for(var k = 0; k < 3; k++) { alert( k ); //分别弹出 0 1 2 } alert( k ); //弹出3 } alert( j ); //弹出0 } rainman(); alert(i); </script>
rainman中的i,j,k可以正常输出,因为它们都在函数rainman中定义的,在函数内都是可用的。
但最后一个alert(i)则会出现脚本运行错误!因为超出了rainman的作用域,i变得不可用!所以说JS是有函数级作用域,但没有block级作用域!
有意思的是第二点。
再一次,引用原文的代码:
<script type="text/javascript"> var x = 1; function rain(){ alert( x ); //弹出 'undefined',而不是1 var x = 'rain-man'; alert( x ); //弹出 'rain-man' } rain(); </script>
为何第一个alert弹出的是undefined???
我的理解是,JS引擎执行函数的时候,会首先根据函数体内的变量声明(注意不是定义!)分配了函数体内所用的变量内存资源,不管这些变量声明的位置是在开头还是结束!
由这个例子进一步,如果var x='rain-man'是有条件的去执行的,JS引擎还会无论如何都先给x分配资源吗??看代码:
<script type="text/javascript"> var x = 1; function rain(){ alert( x ); //弹出 'undefined',而不是1 if(0) var x = 'rain-man'; alert( x ); //弹出 'undefined' } rain(); </script>
答案是肯定的。即使分支不会走到,JS引擎还是无论如何都给x先分配了内存!而一如既往的是,函数内部的x会在函数内部的作用域中覆盖掉外部的x。