JavaScript中this关键字在不同调用方式下的指向差异分析
本文深入探讨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)返回的是全局引用
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
