在学习JavaScript的变量作用域之前,我们应当明确几点:

a、JavaScript的变量作用域是基于其特有的作用域链的。

b、JavaScript没有块级作用域。

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

1、JavaScript的作用域链

首先看下下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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。

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

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript" language="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函数体内都是全局的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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
}
 
</script>

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

首先观察这段代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript" language="javascript">
 
function rain(){
    var x = 1;
    function man(){
        x = 100;
    }
    man();    //调用man
    alert( x );    //这里会弹出 100
}
rain();    //调用rain
 
</script>

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

1
2
3
4
5
6
7
8
9
10
11
<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>

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

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

1
2
3
4
5
6
function rain(){
    var x;
    alert( x );
    x = 'rain-man';
    alert( x );
}

5、未使用var关键字定义的变量都是全局变量。

1
2
3
4
5
6
7
<script type="text/javascript" language="javascript">
function rain(){
    x = 100;    //声明了全局变量x并进行赋值
}
rain();
alert( x );    //会弹出100
</script>

这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。

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

1
2
3
4
5
<script type="text/javascript" language="javascript">
var x = 100 ;
alert( window.x );//弹出100
alert(x);
</script>

等同于下面的代码

1
2
3
4
5
<script type="text/javascript" language="javascript">
window.x = 100;
alert( window.x );
alert(x)
</script>

深入理解Javascript变量作用域的更多相关文章

  1. 【转】javascript变量作用域、匿名函数及闭包

    下面这段话为摘抄,看到网上大多数人使用的是变量在使用的时候声明而不是在顶端声明,也可能考虑到js查找变量影响性能的问题,哪里用就在哪里声明,也很好. 在Javascript中,我们在写函数的时候往往需 ...

  2. 第一百零六节,JavaScript变量作用域及内存

    JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...

  3. JavaScript变量作用域

    全部变量拥有全局作用域,局部变量拥有局部作用域(这里注意函数的参数也是局部变量) 1.在函数体内,局部变量的优先级高于同名的全局变量. 我的理解就是当你同时定义了同名的局部变量和全局变量时,函数体内返 ...

  4. JavaScript变量作用域(Variable Scope)和闭包(closure)的基础知识

    在这篇文章中,我会试图讲解JavaScript变量的作用域和声明提升,以及许多隐隐藏的陷阱.为了确保我们不会碰到不可预见的问题,我们必须真正理解这些概念. 基本定义 作用范围是个“木桶”,里面装着变量 ...

  5. JavaScript 变量作用域

    一. 变量声明 变量用var关键字来声明,如下所示: 变量在未声明的情况下被初始化,会被添加到全局环境. JavaScript执行代码时,会创建一个上下文执行环境,全局环境是最外围的环境.每个函数在被 ...

  6. JavaScript 变量作用域 详解

    变量作用域要点 - 在JavaScript中没有块级作用域,只有函数作用域 - 在函数体内,局部变量的优先级高于同名的全局变量 - 在全局作用域编写代码时可以不写var语句,但声明局部变量时必须使用v ...

  7. 基础系列(1)之干掉JavaScript变量作用域

     今天去某顺公司面试,发现一些基础知识都不记得了,于是乎决定把js基础系列的全部梳理一遍,今天就整理下js变量作用域的相关基础知识点,配合最常遇到的笔试题阐述. 题一: var g = "a ...

  8. 深入浅出JavaScript变量作用域

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

  9. JavaScript 变量作用域和声明提升

    一.变量作用域 说到这个概念,不有自主的想到this,scope 这两个关键字. JavaScript的this总是指向一个明确的对象,这个对象是在执行的时候动态绑定的.通俗的说就是谁调用我,我的th ...

随机推荐

  1. 微信JSSDK录音的一些bug

    UPDATE: 这篇博文已经过期, 新的BUG总结请看微信JSSDK与录音相关的坑 微信JSSDK有不少坑, 最近做一个webapp, 用到了其中的录音功能, 发现不少问题, 总结一下: 当你调用st ...

  2. ruby字符串相关方法

    构造字符串字面量 方法一:最简单的使用单引号或者双引号括起来的字符串,比如"hello". 方法二:使用%q配合分界符,%q代表单引号str=%q!he/lo! 方法三:使用%Q配 ...

  3. 数据库sql整体整理

    create database 数据库 /* 数据库的服务.数据库文件. */ --修改表添加列 create table biao ( name ) ) ) --往表里增加一列 alter tabl ...

  4. CH Round #45 能量释放

    能量释放 CH Round #45 - alan有一些陷阱 III 题目描述 alan得到一块由个能量晶体构成的矿石,对于矿石中的每一个能量晶体,如果用化学物质刺激某一个能量晶体,就能使它释放能量. ...

  5. Reason: Server is in single user mode. Only one administrator can connect at this time

    单击Start→All Programs→Microsoft SQL Server 2008→Configuration Tools→SQL Server Configuration Manager. ...

  6. 用SQL描述树

    /*40条(1层) SELECT COUNT(*) FROM t01_mwfl WHERE AZFSDM=01 AND LEVEL=1 START WITH PID=0 CONNECT BY PRIO ...

  7. Naive and Silly Muggles

    Problem Description Three wizards are doing a experiment. To avoid from bothering, a special magic i ...

  8. 资深系统管理员给Linux/Unix新人们的建议

    根据同事多年跟踪的学员情况,我们发现,学员在同等条件学习Linux后,选择开发要比系统应用薪水要上升的更为迅速,而且更容易突破5000.8000或10000等每月的门槛:但是这个方向难度会更大,同时会 ...

  9. 哈希(2) hash索引

    首先复习:       索引:快速查找的数据结构 1.可以读以下mysql中索引的使用方法,图文并茂.很好理解. http://www.it165.net/database/html/201310/4 ...

  10. JQ绑定事件(1.9已经废除了live()等绑定事件方法,on()方法是官方推荐的绑定事件的一个方法)

    本文来源:http://www.cnblogs.com/leejersey/p/3545372.html jQuery on()方法是官方推荐的绑定事件的一个方法. $(selector).on(ev ...