变量的作用域
一个变量的作用域是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,在js代码中的任何地方都是有定义的。然而在函数声明声明的变量只有在函数体内定义。它们是局部变量。函数参数也是局部的,也只在函数体内有定义。
在函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量所遮盖。
var box="1"; //声明一个全局变量
function check(){
var box="2"; //声明一个同名的局部变量
console.log(box); //打印出变量的值,得到的是局部变量的值,而不是全局变量的值
}
check();
尽管在全局作用域编写代码时可以不写var语句,但是声明局部变量时则必须使用var语句,思考一下如果不这样做会怎样:
box="1"; //声明一个全局变量,不用var
function check(){
box="2";
box2="3";
console.log(box+":"+"box2"); //打印结果是全局变量的值被修改了
}
check():
函数的定义是可以嵌套的。由于每个函数都有它自己的作用域,因此会出现几个局部作用域嵌套的情况,例如:
var box="0"; function check(){ var box="1"; function check2(){ var box="2"; console.log(box); } console.log(box); return check2(); } check(); //打印结果为1,2
在类似C语言的编程中,花括号内的每一段代码都具备有各自的作用域,而且变量在声明他们的代码段之外是不可见的,我们称之为块级作用域,而js中没有块级作用域。js中取而代之的使用了函数作用域:变量在声明他们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
在如下所示代码中,在不同的位置定义了变量i,j,k,他们都在同一个作用域内--这个三个变量在函数体内均是有定义的。
function test(o){ var i = 0; //i在整个函数体内是均有定义的 if (typeof o == "object"){ var j = 0; //j通过打印结果可知j和i的作用域也一样 for(var k = 0; k < 10; k++){ console.log(k); //k同上 } console.log(k); } console.log(j); }
js的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味着变量在声明之前的甚至已经可用。js 的这个特性被非正式的称为声明提前,即js函数里的所有变量(但不涉及赋值)都被“提前”至函数体的顶部,如下代码:
var box = "1"; function f(){ console.log(box); //输出undefined var box="2"; //变量在这里开始赋值 console.log(box); //输出2 }
这里可能会误认为函数第一行会输出“1”,因为代码还没有执行到var语句声明局部变量的地方,其实不然,由于函数的作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖了同名全局变量,尽管如此,只有在函数执行var的时候,局部变量才会真正赋值,因此上述过程等价于,将函数体内的变量声明“提前”至函数体的顶部,同时变量的初始化留在原来的位置,上面的function等效于:
function f(){ var box; console.log(box); //输出undefined box="2"; //变量在这里开始赋值 console.log(box); //输出2 }
在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽量能靠近彼此,这是一个非常好的编程习惯。由于js没有块级作用域,所以程序员特意将变量的声明放在函数体的顶部,而不是将声明靠近放在使用变量之处。这种做法使源代码非常清晰的表示出变量的作用域。
浙公网安备 33010602011771号