c语言变量按其作用域分为|JavaScript变量作用域详解

更新时间:2017-03-07    来源:C语言    手机版     字体:

【www.bbyears.com--C语言】

JavaScript变量作用域详解

变量作用域是程序中定义这个变量的区域。变量的作用范围又称为作用域,是指某变量在程序中的有效范围。根据作用域,变量可以分为全局变量和局部变量。


先贴一段代码,如果读者对代码的输出并不感到困惑就不用往下面读了。

 
JavaScript的变量作用域是基于其特有的作用域链的。
JavaScript没有块级作用域。
函数中声明的变量在整个函数中都有定义。


/*  代码1  */
var scope = "global ";
function checkScope() {
    var scope = "local ";
    function childCheck() {
        var scope = "childLocal ";
        document.write(scope);
    }
    function childUndefined() {
        document.write(scope);
        var scope;
    }
    function childOverride() {
        scope = "childOverride ";
        document.write(scope);
    }
    document.write(scope);  //输出"local"
    childCheck();           //输出"childLocal"
    childUndefined();       //输出"undefined"
    childOverride();        //输出"childOverride"
    document.write(scope);  //输出"childOverride"
}
checkScope();               //输出"local childLocal undefinedchildOverride childOverride"
document.write(scope);      //输出"global "

 

全局作用域与局部作用域
全局(global)变量的作用域是全局的,在Javascript中处处有定义;而函数内部声明的变量是局部(local)变量,其作用域是局部性的,只在函数体内部有定义。对于下面的输出读者应不会感到意外。
/*  代码2  */
var scope = "global";
function checkScope() {
    var scope = "local";
    document.write(scope);
}
checkScope();           //输出"local"
document.write(scope);  //输出"global"

 

全局变量作用域中使用变量可以不用var语句,但在声明局部变量是一定要使用var语句,否则会视为对全局变量的引用。看下面代码:

/*  代码3  */
var scope = "global";
function checkScope() {
    scope = "local";
    document.write(scope);
}
checkScope();           //输出"local"
document.write(scope);  //输出"local"

 

没有块作用域
Javascript没有块级作用域,函数中声明的变量在整个函数中都是有定义的。对于下面的代码对于生疏的读者可能颇感意外:

/*  代码4  */
var scope = "global";
function checkScope() {
    document.write(scope);  //语句4.1
    var scope = "local";    //语句4.2
    document.write(scope);
}
checkScope();           //输出"undefinedlocal"

 

由于语句4.1(var scope = "local";)声明的变量在整个checkScope函数作用域内都有效,因此在语句4.2(document.write(scope); )执行的时scope引用的是局部变量,而此时局部变量scope尚未定义,所以输出”undefined”。因此一个好的编程习惯是将所有的变量声明集中起来放在函数的开头。

在了解了上述内容之后,读者再看看代码1应该不会感到困惑了。

对象的属性变量
对象的属性变量比较容易理解,看一下下面的代码读者应该不会感到疑惑。
/*  代码5  */
var scope = "global ";
var obj = new Object();
obj.scope = "object ";
obj.checkScope = function () {
    var scope = "loacl ";
    document.write(scope);          //输出"loacl"
    document.write(this.scope);     //输出"object"
    document.write(window.scope);   //输出"global"
}
obj.checkScope();   //输出"loacl object global"


看下下面这段代码:

<script type="text/网页特效">
    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。

2、函数体内部,局部变量的优先级比同名的全局变量高。
<script type="text/javascript">
    var rain = 1;    //定义全局变量 rain
    function check(){
        var rain = 100;    //定义局部变量rain
        alert( rain );       //这里会弹出 100
    }
    check();
    alert( rain );    //这里会弹出1
</script>3、JavaScript没有块级作用域。
这一点也是JavaScript相比其它语言较灵活的部分。

仔细观察下面的代码,你会发现变量i、j、k作用域是相同的,他们在整个rain函数体内都是全局的。

<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
    }
</script>
4、函数中声明的变量在整个函数中都有定义。
首先观察这段代码:

<script type="text/javascript">
    function rain(){
        var x = 1;
        function man(){
            x = 100;
        }
        man();        //调用man
        alert( x );    //这里会弹出 100
    }
    rain();    //调用rain
</script>
上面得代码说明了,变量x在整个rain函数体内都可以使用,并可以重新赋值。由于这条规则,会产生“匪夷所思”的结果,观察下面的代码。

<script type="text/javascript">
    var x = 1;
    function rain(){
        alert( x );        //弹出 "undefined",而不是1
        var x = "rain-man";
        alert( x );        //弹出 "rain-man"
    }
    rain();
</script>
是由于在函数rain内局部变量x在整个函数体内都有定义( var x= "rain-man",进行了声明),所以在整个rain函数体内隐藏了同名的全局变量x。这里之所以会弹出"undefined"是因为,第一个执行alert(x)时,局部变量x仍未被初始化。

所以上面的rain函数等同于下面的函数:

function rain(){
    var x;
    alert( x );
    x = "rain-man";
    alert( x );
}
5、未使用var关键字定义的变量都是全局变量。
<script type="text/javascript">
    function rain(){
        x = 100;    //声明了全局变量x并进行赋值
    }
    rain();
    alert( x );    //会弹出100
</script>
这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。

6、全局变量都是window对象的属性
<script type="text/javascript">
    var x = 100 ;
    alert( window.x );//弹出100
    alert(x);
</script>
等同于下面的代码

<script type="text/javascript">
    window.x = 100;
    alert( window.x );
    alert(x)
</script>

在函数内部,局部变量的优先级比同名的全局变量优先级要高;如果存在与全局变量名称相同的局部变量,或者在函数内部声明了与全局变量同名的参数,那么,该全局变量将不再起作用。如下例子:

<script language="javascript" type="text/javascript">

</script>
输出:

我是一个局部变量
       虽然在全局作用域中可以不使用var声明变量,但在声明局部变量时,一定要使用var语句。一般情况下,函数并不知道全局作用域中定义了什么变量,也不知道这些变量的作用。如果函数使用的是全局变量,而不是是局部变量,那么就可能改变程序其他部分所依赖的全局变量的值。因此,最好在声明所有变量时都使用var语句。

       JavaScript没有块级作用域,函数中声明的所有变量无论是在哪里声明的,在整个函数中都有意义。在下面代码中,变量i,j,k作用域相同,在整个函数体中都有意义。看下下面例子:

 

<script language="javascript" type="text/javascript">

</script>
输出:

k在循环体内的值为:0
k在循环体内的值为:1
j在if语句外的值为:1

本文来源:http://www.bbyears.com/asp/31004.html

热门标签

更多>>

本类排行