JavaScript的变量作用域深入理解

在学习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> 
时间: 2024-10-24 04:09:13

JavaScript的变量作用域深入理解的相关文章

[转]深入理解JavaScript的变量作用域

1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定义的变量都是全局变量. 6.全局变量都是window对象的属性 在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. 1.JavaScript的作用域链

深入理解JavaScript的变量作用域(转载Rain Man之作)

在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. 1.JavaScript的作用域链 首先看下下面这段代码: <script type="text/javascript"> var rain = 1; function rainman(){ var man = 2; function inner(){ var innerVa

深入理解JavaScript的变量作用域

在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. 1.JavaScript的作用域链 首先看下下面这段代码: 1 <script type="text/javascript"> 2 var rain = 1; 3 function rainman(){ 4 var man = 2; 5 function inner(){ 6

第九章 Javascript之变量作用域

分析: 无论是强类型语言c#.c++.java等语言,还是弱类型语言如Javascript,所有变量可以抽象为两种类型,即局部变量和全局变量. 全局变量:整个作用域可见. 局部变量:局部可见,退出作用域,就被GC销毁,回收空间. Code分析: //局部变量 function PartVary() { var n = 10; //表示局部变量,外部不可访问 } PartVary(); alert(n);//error //全局变量 function AllVary() { n = 10 //表示

自学JavaScript(一) 变量-作用域

JavaScript 作用域 作用域—可访问变量的集合. 全局变量或者函数可以覆盖window对象的变量或者函数: 局部变量和window对象可以覆盖全局变量和函数. JavaScript 作用域 在 JavaScript 中, 对象和函数同样也是变量. 在 JavaScript 中, 作用域为可访问变量,对象,函数的集合. JavaScript 函数作用域: 作用域在函数内修改. 注:因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量. 局部变量在函数开始执行时创建,函数执行完后

JavaScript的变量作用域

http://www.cnblogs.com/rainman/archive/2009/04/28/1445687.html tag:作用域链 作用域 声明提升 全局变量 http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014344993159773a464f34e1724700a6d5dd9e235ceb7c000 tag:变量作用域 声明提升 全局作用域 命名冲突 ES6(

JavaScript&amp;jQuery.变量作用域

变量作用域 变量的位置或影响它的作用范围,这个作用范围也叫作用域. 如果变量是在函数内声明的,那么的作用域仅在函数内,函数之外不能调用.函数调用执行完后,函数内的变量立即销毁. function getArea(length,width){     // 局部变量area,在函数调用后立马销毁     var area= length*width;     return area; } 如果变量是在函数外声明的,它的作用域是全局的,也叫全局变量.在页面被浏览器加载后,全局变量一直存于内存中,直到

JavaScript 关于变量作用域的一道面试题

ShineJaie 原创,转载请注明出处. 昨晚在一个交流群里看到有位网友提了一个他的面试题求助答疑.刚好我也有看到,就对这个问题思考了一下,觉得这道题对理解 JavaScript 作用域还是很有帮助的,特此又把自己的解题思路梳理了一遍,希望对其它人有所帮助. 首先看下面试题: 1 var arr = [1, 2, 3]; 2 for (var i = 0, j; j = arr[i++];) { 3 console.log(j); 4 } 5 6 console.log('---------'

关于javascript函数变量作用域问题

作用域 1.如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量: 2.JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找.如果内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽"外部函数的变量.