详解JavaScript中this的指向问题

作者:函数茶馆

时间:2026-10-22

浏览:261

本文详细解析JavaScript中this关键字的六种常见指向场景,包括纯函数、对象方法、构造函数、内部函数、call/apply以及事件绑定。通过具体代码示例说明不同调用方式下this的绑定规则,特别是事件绑定中DOM元素与全局对象的差异,帮助开发者避免常见陷阱。

文章目录

JavaScript this指向概述

在面向对象编程语言中,this是一个核心关键字,深入理解并熟练运用它对于编写健壮且优雅的代码至关重要。然而,JavaScript中的this行为与Java、C#等纯面向对象语言存在显著差异,这种特殊性使得this的指向变得复杂且容易令人困惑。

JavaScript中this主要出现在以下几种典型场景中:

1. 纯函数调用

2. 对象方法调用

3. 使用new关键字调用构造函数

4. 嵌套内部函数

5. 使用call或apply方法调用

6. 事件绑定处理

纯函数中的this指向

1. 纯函数调用


var name = 'this is window'; //定义window的name属性 
function getName(){ 
 console.log(this); //控制台输出: Window //this指向的是全局对象--window对象 
 console.log(this.name); //控制台输出: this is window / 
} 
getName(); 

运行结果分析:在纯函数中,this默认指向全局对象,在浏览器环境中即为window对象。

对象方法调用中的this

2. 对象方法调用


var name = 'this is window'; //定义window的name属性,看this.name是否会调用到 
var testObj = { 
 name:'this is testObj', 
 getName:function(){ 
 console.log(this); //控制台输出:testObj //this指向的是testObj对象 
 console.log(this.name); //控制台输出: this is testObj 
 } 
} 
testObj.getName();

运行结果分析:当通过对象调用其方法时,方法内部的this指向调用该方法的对象本身。

构造函数中的this

3. 使用new调用构造函数


function getObj(){ 
 console.log(this); //控制台输出: getObj{} //this指向的新创建的getObj对象 
} 
new getObj();

运行结果分析:在构造函数中使用new关键字时,this指向新创建的实例对象。

内部函数中的this陷阱

4. 内部函数


var name = "this is window"; //定义window的name属性,看this.name是否会调用到 
var testObj = { 
 name : "this is testObj", 
 getName:function(){ 
 //var self = this; //临时保存this对象 
 var handle = function(){ 
 console.log(this); //控制台输出: Window //this指向的是全局对象--window对象 
 console.log(this.name); //控制台输出: this is window 
 //console.log(self); //这样可以获取到的this即指向testObj对象 
 } 
 handle(); 
 } 
} 
testObj.getName();

运行结果分析:在对象方法内部定义的函数(内部函数)中,this依然指向全局对象window。这通常被视为JavaScript语言设计上的一个缺陷,因为开发者通常不希望内部函数继承全局this。常见的解决方案是将外层的this保存到一个变量中,通常约定命名为that或self,如上述代码所示。

call与apply中的this绑定

5. 使用call / apply


var name = 'this is window'; //定义window的name属性,看this.name是否会调用到 
var testObj1 = { 
 name : 'this is testObj1', 
 getName:function(){ 
 console.log(this); //控制台输出: testObj2 //this指向的是testObj2对象 
 console.log(this.name); //控制台输出: this is testObj2 
 } 
}
var testObj2 = { 
 name: 'this is testObj2' 
}
testObj1.getName.apply(testObj2); 
testObj1.getName.call(testObj2);

注意:apply和call的功能类似,主要区别在于第二个参数的传递形式不同:

[1] call( thisArg [,arg1,arg2,… ] ); // 第2个参数使用参数列表:arg1,arg2,...

[2] apply(thisArg [,argArray] ); //第2个参数使用参数数组:argArray

运行结果分析:通过call或apply调用的函数,其内部的this指向被绑定的指定对象。

事件绑定中的this指向

6. 事件绑定

事件处理函数中的this指向往往是开发者最容易产生误解的地方,大部分相关错误都源于此。


//页面Element上进行绑定 
 <script type="text/javascript"> 
 function btClick(){ 
 console.log(this); //控制台输出: Window //this指向的是全局对象--window对象 
 } 
 </script> 
 <body> 
 <button id="btn" onclick="btClick();" >点击</button> 
 </body> 
//js中绑定方式(1) 
 <body> 
 <button id="btn">点击</button> 
 </body> 
 <script type="text/javascript"> 
 function btClick(){ 
 console.log(this); //控制台输出:<button id="btn">点击</button> //this指向的是Element按钮对象 
 }
 document.getElementById("btn").onclick = btClick; 
 document.getElementById("btn").onclick(); //默认点击
 </script>
//js中绑定方式(2) 
<body> 
 <button id="btn">点击</button> 
 </body> 
 <script type="text/javascript"> 
 document.getElementById("btn").onclick = function(){ 
 console.log(this); //控制台输出:<button id="btn">点击</button> //this指向的是Element按钮对象 
 } 
 document.getElementById("btn").onclick(); 
 </script>
//js中绑定方式(3) 
<body> 
 <button id="btn">点击</button> 
 </body> 
 <script type="text/javascript"> 
 function btClick(){ 
 console.log(this); 
 }
 document.getElementById("btn").addEventListener('click',btClick); //控制台输出:<button id="btn">点击</button> //this指向的是Element按钮对象把函数(方法)用在事件处理的时候。 
 document.getElementById("btn").attachEvent('onclick',btClick); //IE使用,控制台输出: Window //this指向的是全局对象--window对象 
 </script>

运行结果分析:上述两种常见的事件绑定方式中,如果在HTML元素上直接进行绑定(例如onclick="btClick();"),this指向全局对象;而在JavaScript代码中进行绑定时,除了IE浏览器特有的attachEvent绑定的事件方法(其this指向全局对象)外,其他绑定方式中this指向触发事件的DOM Element元素。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持本站!

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章