您的位置:首页 > Web前端 > JavaScript

js变量的声明、作用域以及闭包

2016-10-11 15:56 274 查看

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、闭包

aedc

     要理解闭包,首先必须理解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语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

     所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息