JavaScript变量作用域
局部变量和全局变量
首先我们来看一个例子:
if(1){ var a = 110; } console.log(a); // 这里会输出什么呢?
经过试验,我们会发现输出的是100
,这个对于学过C,Java,OC的同学来说,可能有些不可思议。这里我们就要说一下,在JavaScript的作用域是跟类似C语言不同的,它没有块级作用域(<small>所谓块级作用域,就是以花括号包括起来的作用域</small>),而使用的是函数作用域(<small>变量在声明它的函数体以及其嵌套的任意函数体内都是有定义的</small>)。而上面的例子中 a
是什么变量呢,很显然是全局变量。通过例子我们就可以验证了:
if(1){ var a = 110; } function func(){ console.log(a); // 输出100; }
下面我们通过一个例子来看看 全局变量和局部变量
// 全局变量 在任何地方都可以使用
var a = 10 ;
// 另一个全局变量的声明方式
b = 10;
function demo(){
// 局部变量 只能在当前块内使用
var i = 10;
// 这个属于全局变量 在任何地方都可以使用
u = 20;
}
函数作用域和声明提前
函数作用域:变量在 声明他们的函数体 以及 这个函数体嵌套的任意函数体内 都是有定义的。
声明提前,在C或Java语法中,变量都要先声明、后使用,如果未经声明就使用的话,编译阶段就会报错,而JavaScript却能够在变量和函数被声明之前使用它们。其实是在JavaScript编译阶段时对”声明提前了“。看例子吧。
<small>例子:</small>
var scope = "global";
function func(){
console.log(scope); //输出"undefined",而不是global;
var scope = "local"; //变量在这里赋初始值,但变量本身在函数体内任何地方均有定义
console.log(scope); //输出"local"
}
第一行打印的并不是全局变量scope
,而是局部变量scope
,因为在第二行我们看到了局部变量scope
的声明,根据”声明提前“,局部变量scope
的声明提前到了函数体的最顶端。所以才会出现上述的打印结果。上述函数体等价于如下:
var scope = "global";
function func(){
var scope ; // 在函数顶端声明了局部变量
console.log(scope); //局部变量存在,但是其值为”undefined“
scope = "local"; //此处给局部变量赋值
console.log(scope); //输出"local"
}
个人建议:在函数体内使用局部变量的时候,我们尽量将变量的声明放到函数体顶部。这种做法是的我们的代码看起来更加清晰反映了真是的变量作用域。
全局变量
当声明一个JS全局变量时,实际上是给定义了全局对象的一个属性,并且这个属性是不可配置的,也就是说不能通过delete运算符删除的。本文第一例子中,b = 10;
以这种方式给一个未声明的变量赋值的话,此过程JS自动声明一个b
的全局变量。以这种方式创建的变量是全局对象的正常的可配置值属性,并可以删除它们。
var a = 1; //声明一个不可删除的全局变量,也是全局对象的一个不可删除的属性
b = 2; // 声明一个可以删除的全局对象属性
this.c = 3; // 声明一个可以删除的全局对象属性
delete a; // => false 变量并没有被删除
delete b; // => true 变量被删除
delete this.c ; // => true 变量被删除