JavaScript中this关键字在不同调用方式下的指向差异分析

作者:木棉

时间:2026-10-28

浏览:445

本文深入探讨JavaScript中this关键字在不同调用场景下的行为差异。通过对比直接调用、括号包裹及赋值给全局变量三种方式,分析this指向对象、全局对象或受浏览器实现影响的机制。重点解析||运算符对执行上下文的影响,揭示IE、Firefox及Opera在早期版本中的实现差异,帮助开发者理解动态绑定与静态引用的关系。

文章目录

故整理此例以资借鉴:


JavaScript中this关键字在不同调用方式下的指向差异分析

首先执行如下JavaScript代码


<script>


foo = {


'bar': function () {


alert(this);


 },

'toString': function () {


return 'foo';


 }
};

foo.bar();//返回值为"foo"


(foo.bar)();//返回值为"[object Window]"


(foo.bar || null)();//返回值为"[object Window]"


bar = foo.bar; bar();//返回值为"[object Window]"


</script>



直接调用与括号运算的this指向

针对上述代码的分析如下:



foo.bar(); //输出foo


//1. alert隐式调用toString方法,进行类型转换,因foo中重写了toString方法,故结果为foo



(foo.bar)();//输出foo


//2. 此处的执行逻辑与上述相同



(foo.bar || null)();


/*

3. 此处在IE6.0、Mozilla Firefox1.5.0.7及Opera9.0中表现各异,IE与Opera返回object,Mozilla返回foo


暂不论各JS引擎对||运算符的解释差异,此结果与bar方法中的this指向及||运算符特性相关。经||运算后


此处的this已非window。若依C++概念理解,this关键字体现为动态联编而非静态联编,常规示例中


<script>


(function (){


this.div = document.createElement("div");div.innerHTML="never-online";


document.body.appendChild(div);


this.div.onclick = function(){


alert(this.tagName);//此处this指向div,而非匿名函数内的this


 }
})()

</script>


由此可见,此处this的作用域已非foo对象,而是全局作用域。因此alert(this)等同于alert(window);


故输出object



附注:||运算符可能将两个表达式的执行转换为全局范围的比较,因此在IE和Opera中,(foo.bar || null)返回的是全局引用,即:


'bar': function () {


alert(this);//此处this已指向全局this,即window


 },

详细论证见文末代码示例


*/

全局变量赋值对this引用的影响

bar = foo.bar; bar();//返回值为"[object Window]"


/*4.


此处在IE6.0、Mozilla Firefox1.5.0.7及Opera9.0中均返回相同的object,理解前述执行过程后,此句易解


理由同上,此处将foo.bar的引用赋值给全局变量bar,而全局变量均隶属于window引用,见下方代码:


var a = 'never-online';


alert(this.a); //输出never-online


alert(window.a); //输出never-online


若将bar = foo.bar; bar();修改为以下代码,或许更易理解


foo.alert = foo.bar; foo.alert ();


此处foo.alert仍为foo对象的引用,因此foo对象内的this在此处依然有效,并未变为window object


因bar属性属于window,故引用foo.bar时,尽管内部有this,但this引用指向window


*/

再观察将此例修改为如下形式:


<script>


foo = {


'bar': function () {


var oSelf = this;


alert(this.toString);


if (oSelf==window) {


oSelf = foo;


 }

alert(oSelf);


 },

'toString': function () {


return 'foo';


 }
};

window.toString = function () {


alert("引用全局this --- window");


}

foo.bar();


(foo.bar)();


(foo.bar || null)();


bar = foo.bar; bar();


</script>



如此应能明晰原因。



从该例中(foo.bar || null)(); 可见Mozilla的解释器更为“标准”,而Opera和IE的解释方式与Mozilla不同。||运算符的作用导致了不同效果。如前所述,||运算符可能将两个表达式的执行转换为全局范围的比较,因此在IE和Opera中,(foo.bar || null)返回的是全局引用

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章