Javascript和Java、C这些语言不同,它是一种无类型、弱检测的语言。它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变量
js变量作用域可分为:"全局变量"和"局部变量"
"全局变量":申明在函数之外的变量
"局部变量":申明在函数体中的变量,并且只能在当前函数体内访问,如:function(){var a = 0;}
注:在申明变量是凡是没有var关键字,而直接赋值的变量均为全局变量
i=100;//Number类型
i="variable";//String类型
i={x:4};//Object类型
i=[1,2,3];//Array类型
JS的这种特性虽然让我们的编码更加灵活,但也带来了一个弊端,不利于Debug,编译器的弱检测让我们维护冗长的代码时相当痛苦。
二、变量的声明
JS中变量申明分显式申明和隐式申明。
var i=100;//显式申明
i=100;//隐式申明
在函数中使用var关键字进行显式申明的变量是做为局部变量,而没有用var关键字,使用直接赋值方式声明的是全局变量。
当我们使用访问一个没有声明的变量时,JS会报错。而当我们给一个没有声明的变量赋值时,JS不会报错,相反它会认为我们是要隐式申明一个全局变量,这一点一定要注意。
下面就通过几道小例子来熟悉下
1、function test() {
a = 30;
var b = 20;
}
test();
console.log("a="+a); //这里很明显,a为全局变量
console.log("b="+b);//b为局部变量,故在函数test外调用是,提示未定义
2、
var a = 1;
function test() {
console.log("a="+a); //这里a为undefined
/*函数中声明的变量在整个函数中都有定义。如果函数内部有定义变量,即使在定义之前输出但会先执行后面定义语句,然后判断输出结果,所以说声明的变量在整个函数中都是起作用的。*/
var a = 2;
}
test();
3、
给两个小例子作为对比:
var a; function fun() { a = "global"; } console.log(a);//输出undefined
var a; function fun() { a = "global"; }
fun();console.log(a);//输出 global
5、javascript没有块级作用域
function test(){
for(var i = 0 ; i < 3 ; i++){
//i=0,1,2,最后执行到i=3时退出循环
}
console.log(i);//3
}
test();
相当于
function test(){
var i;
for(i = 0; i < 3; i++){
//i=0,1,2,最后执行到i=3时退出循环
}
console.log(i);//3
}
test();
代码一:
- var i=10;
- function a() {
- alert(i);
- };
- a();
代码二:
- var i=10;
- function a() {
- alert(i);
- var i = 2;
- };
- a();
根据“多年”的编程经验你可能觉得这两个代码输出是一样的,但是事实却是第一个代码正常输出了变量的值----10,而第二个代码输出的却是undefined。也许很多人理解不了,但是根据前面的作用域链的图我们就很好理解了。
作用域链图中很明确的表示出:在变量解析过程中首先查找局部的作用域,然后查找上层作用域。在代码一的函数当中没有定义变量i,于是查找上层作用域(全局作用域),进而进行输出其值。但是在代码二的函数内定义了变量i(无论是在alter之后还是之前定义变量,都认为在此作用域拥有变量i),于是不再向上层的作用域进行查找,直接输出i。但是不幸的是此时的局部变量i并没有赋值,所以输出的是undefined。
《JavaScript权威指南》中提出的“没有块级作用域”实际上就是上述的意思。很多时候认为懂了、理解了,其实没有懂,细细的研究一番之后看回过头来再书中那加粗的文字,顿时恍然大悟,其实人家书里说的挺清楚的嘛!