详解JavaScript中this的指向问题


Posted in Javascript onJanuary 20, 2017

this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要。而javascript的this又有区别于Java、C#等纯面向对象的语言,这使得this更加扑朔迷离,让人迷惑。

this使用到的情况:

1. 纯函数

2. 对象方法调用

3. 使用new调用构造函数

4. 内部函数

5. 使用call / apply

6.事件绑定

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。

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均指向了调用该方法的对象。

3.  使用new调用构造函数

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

运行结果分析:new 构造函数中的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,如上述代码所示。

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);

Note:apply和call类似,只是两者的第2个参数不同:

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

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

运行结果分析:使用call / apply  的函数里面的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>

运行结果分析:以上2种常用事件绑定方法,在页面Element上的进行事件绑定(onclick="btClick();"),this指向的是全局对象;而在js中进行绑定,除了attachEvent绑定的事件方法(this指向的是全局对象)外,this指向的是绑定事件的Elment元素。

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

Javascript 相关文章推荐
基于jquery跨浏览器显示的file上传控件
Oct 24 Javascript
DIV+CSS+JS不间断横向滚动实现代码
Mar 19 Javascript
页面加载完毕后滚动条自动滚动一定位置
Feb 20 Javascript
js调用后台、后台调用前台等方法总结
Apr 17 Javascript
js取模(求余数)隔行变色
May 15 Javascript
js 操作符汇总
Nov 08 Javascript
浅析JavaScript中的变量复制、参数传递和作用域链
Jan 13 Javascript
在AngularJS中如何使用谷歌地图把当前位置显示出来
Jan 25 Javascript
js实现分页功能
May 24 Javascript
对TypeScript库进行单元测试的方法
Jul 18 Javascript
vue实现购物车列表
Jun 30 Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
Jul 28 Javascript
详解微信小程序入门五: wxml文件引用、模版、生命周期
Jan 20 #Javascript
浅谈JavaScript异步编程
Jan 20 #Javascript
JavaScript实现事件的中断传播和行为阻止方法示例
Jan 20 #Javascript
小程序开发实战:实现九宫格界面的导航的代码实现
Jan 19 #Javascript
BootStrap组件之进度条的基本用法
Jan 19 #Javascript
微信小程序 页面跳转和数据传递实例详解
Jan 19 #Javascript
js实现符合国情的日期插件详解
Jan 19 #Javascript
You might like
开发大型PHP项目的方法
2006/10/09 PHP
如何使用php判断服务器是否是HTTPS连接
2013/07/05 PHP
php筛选不存在的图片资源
2015/04/28 PHP
PHP的运行机制与原理(底层)
2015/11/16 PHP
详解php用curl调用接口方法,get和post两种方式
2017/01/13 PHP
Laravel如何友好的修改.env配置文件详解
2017/06/07 PHP
yii框架使用分页的方法分析
2019/07/25 PHP
JS 建立对象的方法
2007/04/21 Javascript
js自定义事件代码说明
2011/01/31 Javascript
JavaScript NodeTree导航栏(菜单项JSON类型/自制)
2013/02/01 Javascript
再JavaScript的jQuery库中编写动画效果的指南
2015/08/13 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
2017/03/15 Javascript
JS实现图片点击后出现模态框效果
2017/05/03 Javascript
Angular2.0实现modal对话框的方法示例
2018/02/18 Javascript
jQuery替换节点元素的操作方法
2018/03/18 jQuery
微信小程序动态设置图片大小的方法
2019/11/21 Javascript
js实现简单点赞操作
2020/03/17 Javascript
JavaScript 异步时序问题
2020/11/20 Javascript
[35:39]完美世界DOTA2联赛PWL S2 FTD.C vs Rebirth 第二场 11.22
2020/11/24 DOTA
比较详细Python正则表达式操作指南(re使用)
2008/09/06 Python
python之wxPython应用实例
2014/09/28 Python
利用Python实现命令行版的火车票查看器
2016/08/05 Python
Python实现的中国剩余定理算法示例
2017/08/05 Python
python2.7读取文件夹下所有文件名称及内容的方法
2018/02/24 Python
centos7中安装python3.6.4的教程
2019/12/11 Python
python 发送get请求接口详解
2020/11/17 Python
一套软件测试笔试题
2014/07/25 面试题
道德之星事迹材料
2014/05/03 职场文书
行政专员岗位职责说明书
2014/07/30 职场文书
会计求职信怎么写
2015/03/20 职场文书
最感人的道歉情书
2015/05/12 职场文书
结婚喜宴祝酒词
2015/08/10 职场文书
2019求职信大礼包
2019/05/15 职场文书
redis复制有可能碰到的问题汇总
2022/04/03 Redis
javascript进阶篇深拷贝实现的四种方式
2022/07/07 Javascript
HTML 里 img 元素的 src 和 srcset 属性的区别详解
2023/05/21 HTML / CSS