代码(1)
<script type="text/javascript" language="javascript"> var rain = 1; function rainman(){ var man = 2; function inner(){ var innerVar = 4; alert(rain); } inner(); //调用inner函数 } rainman(); //调用rainman函数 </script>
第一个代码是很容易理解的观察alert(rain);这句代码。JavaScript首先在inner函数中查找是否定义了变量rain,如果定义了则使用inner函数中的rain变量;如果inner函数中没有定义rain变量,JavaScript则会继续在rainman函数中查找是否定义了rain变量,在这段代码中rainman函数体内没有定义rain变量,则JavaScript引擎会继续向上(全局对象)查找是否定义了rain;在全局对象中我们定义了rain = 1,因此最终结果会弹出'1'。
作用域链:JavaScript需要查询一个变量x时,首先会查找作用域链的第一个对象,如果以第一个对象没有定义x变量,JavaScript会继续查找有没有定义x变量,如果第二个对象没有定义则会继续查找,以此类推。
上面的代码涉及到了三个作用域链对象,依次是:inner、rainman、window。
紧接着第二个问题来了JavaScript没有块级作用域。
这一点也是JavaScript相比其它语言较灵活的部分。
仔细观察下面的代码,你会发现变量i、j、k作用域是相同的,他们在整个rain函数体内都是全局的。 看到这里也是很好理解的,可是调用rainman()的下面我又创建了一个函数function() fn1{alert(j)} 为什么不能调用了? 第一个代码证明他会沿着作用域链去找一直到window对象。为什么ijk在rainman中管用,我在创建一个函数就不管用了?
<script type="text/javascript" language="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() funtion fn1(){alert(j)} //这里表示很疑惑! fn1() </script>
第三个问题有点白痴如下代码 x=100 等于全局函数改变可以改变相同命名的var x这不奇怪。但是如果我把下面的x=100改成var x=100呢?还有为什么我在调用rain()的位置下面输入man(),会无效?只能在rain中运行这是为什么?
<script type="text/javascript" language="javascript"> function rain(){ var x = 1; function man(){ x = 100; } man(); //调用man alert( x ); //这里会弹出 100 } rain(); //调用rain </script>
第四个问题简单明了 下面的代码为什么会是这个输出结果。道理我是知道的预解析
先找var function 参数。然后执行代码 function内第一行的相当于var x;然后alert(x)当然是undifined。但是自从学了作用域链以后总感觉他会想上去找这个X或者去找下面的那个X。在或者JS有变量提升的特性自动把var挤上面去。为什么没有?
如果不弄得明明白白清清楚楚以后难免会犯错
<script type="text/javascript" language="javascript"> var x = 1; function rain(){ alert( x ); //弹出 'undefined',而不是1 var x = 'rain-man'; alert( x ); //弹出 'rain-man' } rain() </script>
Walk_