深入理解JavaScript变量作用域

  JS变量作用域特点:

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

  b、JavaScript没有块级作用域。

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

1、作用域链

var rain = 1 ;
function rainman(){
     var man = 2 ;
     function inner(){
        var innerVar = 4;
        alert(rain);
    }
    inner();     // 调用inner函数
}
rainman();     // 调用rainman函数 

  观察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、函数体内部,局部变量的优先级比同名的全局变量高。

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

3、JavaScript没有块级作用域。

  这一点也是JavaScript相比其它语言较灵活的部分。

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

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 );     // 在for循环外,却依然弹出3
    }
    alert(j);     // 在if语句外,却依然弹出0
}

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

  声明前置规则:声明会提前,但是赋值仍是在赋值的那行代码上赋值;在此之前都为undefined

function  rain(){
    var  x  =   1 ;
    function  man(){
        x  =   100 ;
    }
    man();     // 调用man
    alert( x );     // 这里会弹出 100
}
rain();     // 调用rain 

  上面得代码说明了,变量x在整个rain函数体内都可以使用,并可以重新赋值(当然函数内部不调用man()方法,x 还是弹出 1 咯)。由于这条规则,会产生 “ 匪夷所思 ” 的结果,观察下面的代码。

var  x  =   1 ;
function  rain(){
    alert( x );     // 弹出 ‘undefined‘,而不是1
    var  x  =   ‘ rain-man ‘ ;
    alert( x );     // 弹出 ‘rain-man‘
}
rain()

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

  所以上面代码等价于:

function  rain(){
    var  x;
    alert( x );
    x  =   ‘rain-man ‘ ;
    alert( x );
}

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

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

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

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

var  x  =   100  ;
alert( x === window.x ); // 弹出true
时间: 2024-12-22 16:13:52

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

JavaScript变量作用域和内存问题(js高级程序设计总结)

1,变量 ECMAScript和JavaScript是等同的吗?个人认为是否定的.我的理解是这样的,ECMAScript是一套完整的标准或者说协议,而JavaScript是在浏览器上实现的一套脚本语言.也就是说,ECMAScript是JavaScript的父类标准.JavaScript是ECMAScript的具体实现.所有ECMAScript定义的数据类型或者语言特性实际上都是伪代码的形式规定的.当然如果可以,ECMAScript也可以有服务器实现,单片机实现(不一定恰当).如果说ECMAScr

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

JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变. 一.变量及作用域 1.基本类型和引用类型的值 ECMAScript变量可能包含两种不同的数据类型的值:基本类型值和引用类型值.基本类型值指的是那些保存在栈

javascript 变量作用域[初级简单]

通过一下3个小例子先去理解一下变量作用域的作用. 1----------------------------function aaa(){ var a=12; //局部变量:定义在一个函数里,只能在这个函数里用} function bbb(){ alert(a);//a is not defined} aaa();bbb();2-----------------------------var a; //全局变量:不定义在任何一个函数里,可以在任何地方去用 function aaa(){ a=12

JavaScript变量作用域

全部变量拥有全局作用域,局部变量拥有局部作用域(这里注意函数的参数也是局部变量) 1.在函数体内,局部变量的优先级高于同名的全局变量. 我的理解就是当你同时定义了同名的局部变量和全局变量时,函数体内返回的将是局部变量的值. 例如: var scope="我是全局变量"; function checkscope(){ var scope="我是局部变量"; console.log(scope); } checkscope(); 输出:我是局部变量 这里需要注意的是,在

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

在这篇文章中,我会试图讲解JavaScript变量的作用域和声明提升,以及许多隐隐藏的陷阱.为了确保我们不会碰到不可预见的问题,我们必须真正理解这些概念. 基本定义 作用范围是个“木桶”,里面装着变量.变量可以是局部或者全局性的,但在子范围中定义的变量是可以访问父范围的,这一点可能会造成一些困扰. 在JavaScript中使用"var"关键字声明变量.一旦在父范围宣声明,就会作为各自子范围的一部分.即在本地范围内有效,但本地定义的变量不可在全局范围内访问. 让我们来看一个例子.执行下面

深入浅出JavaScript变量作用域

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

javascript变量作用域与内存

第四章 变量作用域与内存基本类型 5种Undefined Null Boolean Number String 两种变量类型 基本类型与引用类型注意:String 再其他语言中是引用类型,再javascri中为基本类型即:这五种基本类型是按值访问的 引用类型是按照引用访问的 动态的属性对于一个引用类型,一个引用变量被赋值后,可以为其添加属性,也可以删除与修改其属性var o = new object();o.name = "qi"; //可以为引用变量添加属性 变量的复制基本类型的复制

JavaScript 变量作用域 详解

变量作用域要点 - 在JavaScript中没有块级作用域,只有函数作用域 - 在函数体内,局部变量的优先级高于同名的全局变量 - 在全局作用域编写代码时可以不写var语句,但声明局部变量时必须使用var语句 - 函数作用域是指在函数内声明的所有变量在函数体内始终是可见的,变量在声明之前已经可用JavaScript的这个特性被非正式的称为*声明提前* - 函数内的变量声明提前至函数体顶部,同时变量初始化留在原来的位置 - 但声明一个JavaScript全局变量时,实际上是定义了全局对象的一个属性

深入理解javascript的作用域--函数声明为什么会前置

标签: javascript函数对象 这篇博文解决了以下迷惑 函数声明为什么前置 函数声明前置和变量前置优先级问题 为什么js文件开头就可以使用Math,String等库,而不需要导入头文件 1.变量对象VO 变量对象(Variable Object, 缩写为VO)是一个抽象 概念中的"对象",它用于存储执行上下文中的: 1. 变量 2. 函数声明 3. 函数参数 js解释器就是通过变量对象(VO)来找到我们定义的变量和函数的. 举个例子: var a = 10; function t