JavaScript中的变量作用域介绍
内容摘要
对于变量的作用域(scope),C、Java等语言采取的是“block scope”的方式。与之不同,JavaScript所采取的是“function scope”的方式 — 变量的作用域仅由所处的function决定,与i
文章正文
对于变量的作用域(scope),C、Java等语言采取的是“block scope”的方式。与之不同,JavaScript所采取的是“function scope”的方式 — 变量的作用域仅由所处的function决定,与if、for等逻辑块无关。比如,以下这个例子展示了JavaScript中与C、Java等语言不一样的行为:
JavaScript中变量的储存,可以很好的理解JS中的“function scope”与hoisting。由于变量是储存在全局对象或者函数调用对象上的,因此当在function中定义变量时,无论这个变量定义在function的什么地方,这次function调用所使用的函数调用对象中必然会出现一个与此变量同名的属性。如此一来,function中的任何地方都可以访问到该变量。
var x = "test";
function(){
//level-1 function
var x = "temp";
function(){
//level-2 function
var x = "real";
//try to access x here. x will be "real".
}
}
with(o){
//code use properties of object o.
}
涉及到函数调用,JavaScript中还有一个更有趣的概念:变量的作用域链 — 由于变量是储存在全局对象或者函数调用对象上的,因此在访问变量时,可以从多个对象上获取值。以下面的代码为例:
复制代码 代码如下:
var x = "test";
function(){
//level-1 function
var x = "temp";
function(){
//level-2 function
var x = "real";
//try to access x here. x will be "real".
}
}
在上述代码中2级函数(level-2 function)的内部,当试图访问x变量时,程序可以从3个对象上搜索相应的属性值:调用2级函数所使用的函数调用对象、调用1级函数所使用的函数调用对象、全局对象 — 根据函数定义的嵌套关系,JavaScript将生成一个由全局对象和函数调用对象所组成的对象链。访问变量时,程序将从离访问语句最近的那个对象开始搜索,如果没有搜索到,则在对象链中上一级的对象中继续进行搜索,直至全局对象。
由于这个对象链与变量的作用域有关,因此也叫做“作用域链”。
如果需要临时改变作用域链,将某个对象插入到作用域链的最前端(作为最先访问到的那个函数对象),可以使用with语句:
复制代码 代码如下:
with(o){
//code use properties of object o.
}
不过,在JavaScript严格模式下,with语句是被禁用的;即使在非严格模式下,也不推荐使用with语句。
代码注释