1、变量的声明
- 使用var多次声明同一个变量,是合法的,不会因此语法的错误;重复的声明并初始化变量值,只是相当于普通的赋值语句。
- 读取一个未声明的变量值,js会产生一个错误。
- 尝试给一个未经var 声明的变量赋值,js会隐式声明该变量,隐式声明的变量被创建为全局变量。
- 无论是全局变量还是局部变量,最好都使用var进行声明。
- 如果在var中没有初始化变量的值,则默认为undefined.
- 当要声明一个变量并进行初始化,但又不想指定任何特殊值,可以赋值为 JScript 值 null。比如:var bestAge = null;
- 在 JScript 中 null 和 undefined 的主要区别是 null 的操作象数字 0,而 undefined 的操作象特殊值NaN (不是一个数字)。对 null 值和 undefined 值作比较总是相等的。
- 要想显式地将字符串转换为整数,使用 parseInt 方法。要想显式地将字符串转换为数字,使用 parseFloat 方法。请注意,比较大小时字符串自动转换为相等的数字,但加法(连接)运算时保留为字符串。
2、变量的作用域
全局(global)变量的作用域是全局的,即在js代码中处处有定义。
局部(local)变量的作用域是局部性的,只在特定的范围内,比如函数内部定义的变量,函数的参数变量,这些变量的作用范围是局限在函数的内部的。
1.声明全局变量可以不适用var 关键字,局部变量则必须使用var关键字来声明,为了避免不必要的麻烦,养成所有的变量都使用var关键字来声明。
2.变量的定义没有块级作用域
例:
function fn() {
alert(fag); //提示undefined
var fag = 'green';
alert(fag); //提示green
}
问:第一次alert提示fag undefined ,而我们又定义了全局变量fag?????
解析:由于变量的定义没有块级作用域这个规则的限制,局部变量在整个函数内部都是有定义的,这就意味着整个函数体中都隐藏了同名的全局变量,
第一次alert, 局部变量fag是已经被声明了,但是没有初始化值,所以提示undefined;
而第二次的alert,是在 = "green" 之后的,也就是局部变量fag完成了初始化,所以提示为green。
该例子中的代码相当于
function fn() {
var fag; //声明局部变量fag, 没有初始化
alert(fag);
var fag = 'green'; //初始化fag
alert(fag);
}
3、未定义的变量和未赋值的变量
未定义的变量:指没有声明并且没有初始化的变量,尝试读取这种变量会产生一个错误。
注 : 这里要区分开没有声明但初始化了的变量,这种变量不会引起错误,程序会在全局变量中隐式的声明该类变量。
未赋值的变量:指已经声明但没有初始化的变量,尝试读取该类变量将得到一个默认值undefined.
4、闭包
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。另一方面,在函数外部自然无法读取函数内的局部变量。这里有一个地方需要注意, 函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数的内部,再定义一个函数。
function fn1() {
var n=999;
function fn2 () {
alert(n);//999
}
}
在上面的代码中,函数fn2就被包括在函数fn1内部,这时fn1内部的所有局部变量,对fn2都是可见的。但是反过来就不行,fn2内部的局部变量,对fn1 就 是不可见的。这就是Javascript语言特有的“链式作用域”结构(chain scope),
子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
既然fn2可以读取fn1中的局部变量,那么只要把fn2作为返回值,我们不就可以在fn1外部读取它的内部变量了吗!
function fn1() {
var n=999;
function fn2 () {
alert(n);
}
return fn2;
}
var result = fn1();
result();//999
上面代码中的fn2函数,就是闭包。
各种专业文献上的“闭包”(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。