JS作用域的几个问题求解答

以下第一个代码是很容易理解的观察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。
代码(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> 

紧接着第二个问题来了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挤上面去。为什么没有?
如果不弄得明明白白清清楚楚以后难免会犯错

<br> var x = 1; <br> function rain(){ <br> alert( x ); //弹出 &#39;undefined&#39;,而不是1 <br> var x = &#39;rain-man&#39;; <br> alert( x ); //弹出 &#39;rain-man&#39; <br> } <br> rain() <br>

3个回答

第二个问题,你定义的是局部变量,不会被全局调用,只能在函数内调用,而全局变量可以全局调用,
第三个问题和第二个问题的原因是一样的,不要忘记,函数也是变量的一种类型,所以你在函数内部定义的变量,无法被全局调用,
第四个问题,如果有局部变量和全局变量同名,优先调用局部变量,所以,第一次调用的时候,他会去找X,找一下,看到有局部变量,那么就是他了,但是这个时候还没定义,输出undefined,第二次输出rain-main,如果你不声明局变量,那他会直接调用全局变量,就是都输出1,

第二个问题解答: 每次执行一个函数会创建该函数的执行环境,然后在这个执行环境下创建活动对象,这个活动对象链接这个函数的作用域,从而形成这个函数的作用域链,然后是在这个函数的作用域链上访问变量,函数执行完成后执行环境被销毁,所以变量就被销毁了。每次执行这个函数,每次创建执行环境,变量都是处于初始化状态,所以执行完函数后,变量被销毁了,是访问不到的

立即提问
相关内容推荐