js的变量,变量作用域,作用域链
浏览数:46 /
时间:2015年06月09日
变量声明:
使用var关键字声明,如果使用没有声明的变量,则JS会自动声明此变量根据变量作用域。如果变量只声明为赋值,则此时值是undefined。重复声明变量,在JS不会报错,会依据最后一次的声明来处理变量。
变量作用域:
一个变量的作用域是,程序代码定义这个变量的区域,全局变量在程序代码内任何地方都可以访问。
包括在{}函数,对象内的变量(属性)成为局部变量。
在函数体内定义的变量成为局部变量,作用域也是局部,函数参数也是局部变量。
他们只在函数体内有意义。
在函数体内,局部变量优先于全局变量,也就是说当局部变量与全局变量重名时,会优先使用局部变量。在函数体内定义变量时一定要使用var关键字,或者JS会查早同名全局变量并使用。
函数可以嵌套,父函数定义的变量可以在子函数内有意义。
Var space=’op’;
Function par(){
Var space = ‘par’;
Function son(){
Return space;
}
}
Par(); // => par
Var space=’op’;
Function par(){
Var space = ‘par’;
Function son(){
Var space = ‘son’;
Return space;
}
}
Par(); // => son
函数变量作用域和声明提前。
变量声明在这个函数体内以及这个函数嵌套的任意函数体内都是有定义。
JS的函数作用域意味着:定义的变量在函数体内是始终是可见,这意味这变量在在函数体内声明之前就可以使用。
Var space =’global’;
Function test(){
Console.log(space); //=>undefined 变量虽有定义但是没有值
Var space;space=’function’; //变量在这里赋予初始值,但是变量在函数体内都是有定义的(var space);
Console.log(space); //=> function 变量以赋予初始值
}
注意:由于函数作用域的作用,在函数体内的定义变量,在函数内始终有定义,也就是说JS在检测函数有定义变量的语句时会提前声明变量,而不赋值,当执行到赋值语句的时候的才会给与变量赋值。因此上边代码等于:
Var space =’global’;
Function test(){
Var space;
Console.log(space); //=>undefined 变量虽有定义但是没有值
Var space;space=’function’; //变量在这里赋予初始值,但是变量在函数体内都是有定义的(var space);
Console.log(space); //=> function 变量以赋予初始值
}
JS函数独有这个特性叫做 声明提前。
作为属性的变量:
当生命一个全局变量变量时,实际上定义了一个全局对象的属性,当通过var关键字时次属性是不可配置,不能使用delete删除此变量。当不严格的定义(不实用var)是可以通过delete删除。
JS全局变量是全局对象的属性,局部变量没定义,但是也可以想到是函数对象的属性。
JS 允许使用this来引用全局变量,但是没方法可以引用局部变量。
JS作用域链:
JS是基于词法作用域的:全局变量在程序中始终有意义,局部变量在函数体内及函数嵌套的函数体内始终有意义。
如果将变量看作一个自定义实现的对象的属性,那么换一个角度来解读变量作用域。每一段代码都是有一个与之关联的作用域链。这个作用域链对应着一个对象的列表或者链表。那么当执行程序的时候,JS会一次查找每个对象的作用域链。当发现此变量的时候就定义此变量,当没有此变量就抛出一个错误。
那么对于顶层代码来说(不包含函数定义的语句),就会有一个全局作用域链。
对一个不包含嵌套函数的函数作用域链上包含两个对象:参数变量,局部变量的一个对象,和全局变量对象 。
对于嵌套函数来说:
至少有三个对象::参数变量,局部变量的一个对象,和全局变量对象 。
当定义一个函数保存一个作用域链,当调用这个函数的时候,会创建一个更长的函数调用的对象加到这个作用域链,对于嵌套函数来说更复杂,会重新定义内部函数,并创建一个新的对象加到作用域链。因次每次调用外部函数时作用域链都是不相同的。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。