码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript的变量作用域深入理解

时间:2014-09-29 13:31:00      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   使用   ar   java   for   sp   

在学习JavaScript的变量作用域之前,我们应当明确几点:
a、JavaScript的变量作用域是基于其特有的作用域链的。
b、JavaScript没有块级作用域。
c、函数中声明的变量在整个函数中都有定义。

<script>
var x = 1;
function outer() {
    var y = 2;
    function inner() {
        var z = 4;
        alert(x);
    }
    inner(); 
}
outer(); 
</script>

alert(x)这句代码,JavaScript首先在inner函数中查找是否定义了变量x,如果定义了则使用inner函数中的x变量;
如果inner函数中没有定义x变量,JavaScript则会继续在rainman函数中查找是否定义了x变量,在这段代码中outer函数体内没有定义x变量,则JavaScript引擎会继续向上(全局对象)查找是否定义了x;
在全局对象中我们定义了x = 1,因此最终结果会弹出‘1‘。
作用域链:JavaScript需要查询一个变量x时,首先会查找作用域链的第一个对象,如果以第一个对象没有定义x变量,JavaScript会继续查找有没有定义x变量,如果第二个对象没有定义则会继续查找,以此类推。
上面的代码涉及到了三个作用域链对象,依次是:inner、outer、window。

 

2、函数体内部,局部变量的优先级比同名的全局变量高。

<script>
var x = 1;
function check() {
    var x = 100; //定义局部变量x
    alert(x); //这里会弹出 100
}
check();
alert(x); //这里会弹出1
</script>

 

3、JavaScript没有块级作用域。
这一点也是JavaScript相比其它语言较灵活的部分。
仔细观察下面的代码,你会发现变量a、b、c作用域是相同的,他们在整个inner函数体内都是全局的。

<script>
function inner() {
    var a = 0;
    if (1) {
        var b = 0;
        for (var c = 0; c < 3; c++) {
            alert(c); // 分别弹出 0 1 2
        }
        alert(c); //弹出3 
    }
    alert(a); //弹出0
    alert(c); //弹出3 
}
inner();
alert(c); //不弹值 ,如果将var c = 0 中 var 去掉,则会弹出 3
</script>

对于有块级作用域的语言来说,for语句中定义并初始化的变量i在循环外是无法访问的,而在javascript中,for语句中定义的变量c在循环结束后,依旧会存在于循环外部的执行环境(作用域)中,在这里c的作用域是全局环境。具体来说就是:使用var关键字声明变量时,这个变量会自动添加到距离最近的可用环境中。对于函数而言,这个最近的环境就是函数的局部环境。
如果变量在未经声明的情况下被初始化,则该变量会被自动添加到全局环境。
不过有时候的确很需要块级作用域来解决一些问题,这时候我们就可以使用匿名函数来模仿块级作用域。
匿名函数就是没有名字的函数,有时候也被称为拉姆达(lamda)函数。形式如下:
(function(){
//块级作用域
})();
以上代码的意思是:首先定义并立即调用一个匿名函数。将函数声明包含在圆括号中,表示它实际上是一个函数表达式。而紧随其后的另一对圆括号表示立即调用这个函数。
当匿名函数执行完毕,其作用域链立即销毁,从而可以减少闭包占用资源问题。

 

4、函数中声明的变量在整个函数中都有定义。 

<script>
function outer() {
    var x = 1;
    function inner() {
        x = 100;
    }
    inner(); 
    alert(x); //弹出 100
}
outer(); 
</script>

上面代码说明了,变量 x 在整个 outer 函数体内都可以使用,并可以重新赋值。
由于这条规则,会产生“匪夷所思”的结果,观察下面的代码。

<script> 
var x = 1;
function inner() {
    alert(x); //弹出 ‘undefined‘,而不是1
    var x = 2;
    alert(x); //弹出 2
}
inner();
</script> 

这是由于在函数 inner 内局部变量 x 在整个函数体内都有定义 var x= 2,进行了声明 ) , 所以在整个 inner 函数体内隐藏了同名的全局变量 x 。
这里之所以会弹出 ‘undefined‘ 是因为,第一个执行 alert(x) 时,局部变量 x 仍未被初始化。

所以上面的 inner 函数等同于下面的函数。 

<script> 
function inner() {
    var x;
    alert(x);
    x = 2;
    alert(x);
}
</script> 

 

5、未使用var关键字定义的变量都是全局变量。
这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。

<script> 
function inner() {
    x = 100; // 声明了全局变量x并进行赋值
}
inner();
alert(x); //会弹出100
</script> 

 

6、全局变量都是window对象的属性 

<script> 
var x = 100;
alert(window.x); //弹出100
alert(x);
</script> 

等同于下面的代码 

<script> 
window.x = 100; 
alert( window.x ); 
alert(x) 
</script> 

 

JavaScript的变量作用域深入理解

标签:style   blog   color   io   使用   ar   java   for   sp   

原文地址:http://www.cnblogs.com/bigdesign/p/3999747.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!