本文探讨JavaScript中变量作用域与this指针的核心机制。指出ECMAScript仅存在全局和函数两种执行环境,块级语句如for或try/catch无法形成独立作用域,变量仍可在外部访问。同时详细解析this在不同调用场景下的指向:全局环境指向window,普通函数默认指向window,构造函数调用指向实例对象,并提及可通过apply或call改变this引用。
JavaScript变量作用域机制
这一观点在ECMAScript规范中得到了准确体现:系统中仅存在全局执行环境和函数执行环境两种作用域,每个函数定义都会创建一个新的执行上下文,即便存在嵌套函数也是如此。这意味着,即使变量声明被包裹在大括号内,只要未处于函数内部,该变量依然可以在括号外部被访问。以下通过具体代码示例进行说明:
代码如下:
for(var i=0; i<5; i++) {
var num = 20; // 在for语句中声明的变量
}
alert(num); // 在for语句外部调用变量,仍然可以得到num的值 对于异常处理语句同样适用此规则:
代码如下:
try {
var num = 20; // 在try语句中声明的变量
a = b; // 引起一个异常
} catch(e) {
alert(num); // 在catch语句中调用变量,将得到20
} finally {
alert(num); // 在finally语句中调用变量,将得到20
}
alert(num); // 在try语句外部调用变量,将得到20 除了上述两种情况外,单纯的一对大括号也无法构成独立的执行环境。例如:
代码如下:
{ var num = 1;3 } 二、this指针:[P83]
this指针在不同场景下的指向
在此列出this在ECMAScript中的不同含义:
(1) 在全局执行环境中使用this,表示Global对象,在浏览器中就是window对象。
(2) 当在函数执行环境中使用this时,情况就有些复杂了。如果函数没有明显的作为非window对象的属性,而只是定义了函数,不管这个函数是不是定义在另一个函数中,这个函数中的this仍然表示window对象。如果函数显示地作为一个非window对象的属性,那么函数中的this就代表这个对象。(当然可以使用apply或者call函数来取代默认this的引用,详见[P88])
(3) 当通过new运算符来调用函数时,函数被当做一个构造函数,this指向构造函数创建出来的对象。
参考:
《JavaScript基础与案例开发详解》清华大学出版社