JavaScript变量的作用域

原创
2016/03/09 00:46
阅读数 201

    虽然《JavaScript权威指南》这本书很好,但是有一些东西让人容易理解错。最近在恶补基础,结合这本书,我想把变量的作用域重新梳理一下:

    "一个变量的作用域(scope)是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的。然而在函数内声明的变量只在函数体内有定义。"----摘自《JavaScript权威指南》第6版


     "在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明他们的代码段之外是不可见的,我们称之为块级作用域。"----摘自《JavaScript权威指南》第6版


    在ECMAScript 6之前是没有块级作用域的,这里说的是ECMAScript5.1规范标准。

    变量分全局变量,局部变量。这就决定了变量的作用域:全局作用域、与函数作用域

demo1:

var scope = "global"; //声明一个全局变量
function check() {    
    var scope = "local";    //声明一个同名的局部变量
    return scope;        //返回局部变量的值,而不是全局变量的值
}
check();        => "local"

解:

    " 在函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明的一个局部变量or函数参数中带有的变量和全局变量重名,那么全局变量就会被局部变量所遮盖。"----摘自《JavaScript权威指南》第6版

实践证明:

var scope = "global"; //声明一个全局变量
function check() {    
    var scope = "local";    //声明一个同名的局部变量
    return scope;        //返回局部变量的值,而不是全局变量的值
}
check();        => "local"
console.log(scope);      =>"blobal"

    书上的话容易误导人,很多人一开始把这里的"遮盖"当成了覆盖,想当然认为全局变量scope的值变成了"local",实则不然。 在函数体内,局部变量的优先级高于同名的全局变量。其实check函数返回就是局部变量scope,而不是全局变scope;两者只是同名而已。


demo2:

scope = "global"; //声明一个全局变量,不使用var声明
function t() {    
    scope = "local";    //修改了全局变量
    myscope = "local;    //声明一个新的全局变量
    return [scope,myscope];        //返回两个值
}
t();        scope => "local"    myscope => "local" //两者都为 "local"

解:

    在js中,如果给一个没有声明的变量赋值,都是全局变量,而且是全局对象的属性。


demo3:

var scope="global";  //声明一个全局变量
function t(){  
    console.log(scope);  
    var scope="local"  
    console.log(scope);  
}  
t();     scope => 第一次为 undefined      第二次才为 "local"

解:

       很多人勿认为第一次打印的是全局变量,其实不然。 js函数作用域:指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味着变量在声明之前甚至已经可用。js这个特性被非正式地成为声明提前。即:js函数里声明的所有变量都(不涉及赋值)被“提前”到函数体的顶部。

    上述过程等价:将函数内的变量声明“提前”至函数体顶部,变量初始化留在原来的位置。等价于如下的代码:

var scope="global";  //声明一个全局变量
function t(){  
    var scope;    //顶部声明了局部变量
    console.log(scope);  //变量存在,但未初始化
    scope="local"     //初始化并赋值
    console.log(scope);  
}  
t();


函数内声明的变量都是局部变量,函数外是无法访问的,外部想要访问函数内的变量可以采用闭包来实现,代码实例如下:

demo4:

function t (){
    var x=10;
    return function () {
        return x;
    }
}
console.log(x);    //报错,x未定义
var a = t();
console.log(a());    //10


在js编写当中,由于规范太少,写法灵活,可能导致出现各种bug。声明变量时,最好放在函数体顶部,增加易读性。

es6中,增加了很多特性,js的规范越来越标准化,已成为一门通吃各个平台的语言,加油!

展开阅读全文
打赏
1
5 收藏
分享
加载中
mosaic101博主

引用来自“甩葱哥”的评论

那书翻译的一些地方代码举例不恰当,我觉得是翻译问题,知识求证可以试试原文版本。
谢谢指点,翻译虽然有点生涩,不过总比光看英文好
2016/03/11 22:37
回复
举报
那书翻译的一些地方代码举例不恰当,我觉得是翻译问题,知识求证可以试试原文版本。
2016/03/11 01:34
回复
举报
mosaic101博主

引用来自“LeisureZjj”的评论

博主的学习思路很细心、深入,让自己更加理解js中作用域的情况。受教了。
不客气
2016/03/09 13:09
回复
举报
博主的学习思路很细心、深入,让自己更加理解js中作用域的情况。受教了。
2016/03/09 06:26
回复
举报
更多评论
打赏
4 评论
5 收藏
1
分享
返回顶部
顶部