详解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 相关文章推荐
javascript的函数
Jan 31 Javascript
javascript div 弹出可拖动窗口
Feb 26 Javascript
js表格分页实现代码
Sep 18 Javascript
高效的表格行背景隔行变色及选定高亮的JS代码
Dec 04 Javascript
jquery zTree异步加载简单实例分享
Feb 05 Javascript
基于JavaScript 声明全局变量的三种方式详解
May 07 Javascript
javascript实现无限级select联动菜单
Jan 02 Javascript
Javascript中的对象和原型(二)
Aug 12 Javascript
jQuery zTree树插件简单使用教程
Jan 10 Javascript
JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析
Sep 05 Javascript
利用jqprint插件打印页面内容的实现方法
Jan 09 Javascript
JavaScript执行机制详细介绍
Dec 06 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
DOTA2 6.87版本后新眼位详解攻略
2020/04/20 DOTA
php 上传功能实例代码
2010/04/13 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
ThinkPHP3.2.3框架Memcache缓存使用方法实例总结
2019/04/15 PHP
jquery异步请求实例代码
2011/06/21 Javascript
jQuery EasyUI API 中文文档 - DataGrid数据表格
2011/11/17 Javascript
javaScript 删除字符串空格多种方法小结
2012/10/24 Javascript
table行随鼠标移动变色示例
2014/05/07 Javascript
js类定义函数时用prototype与不用的区别示例介绍
2014/06/10 Javascript
javascript中的this详解
2014/12/08 Javascript
浅谈javascript函数式编程
2015/09/06 Javascript
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
Angular5中状态管理的实现
2018/09/03 Javascript
Javascript 实现 Excel 导入生成图表功能
2018/10/22 Javascript
JS使用H5实现图片预览功能
2019/09/30 Javascript
vue 强制组件重新渲染(重置)的两种方案
2019/10/29 Javascript
Vue如何获取数据列表展示
2019/12/11 Javascript
JavaScript正则表达式验证登录实例
2020/03/18 Javascript
vue中watch和computed的区别与使用方法
2020/08/23 Javascript
vue 子组件和父组件传值的示例
2020/09/11 Javascript
使用Python编写vim插件的简单示例
2015/04/17 Python
Swift中的协议(protocol)学习教程
2016/07/08 Python
Django项目中用JS实现加载子页面并传值的方法
2018/05/28 Python
python实现括号匹配的思路详解
2018/08/23 Python
使用memory_profiler监测python代码运行时内存消耗方法
2018/12/03 Python
python3.9.1环境安装的方法(图文)
2021/02/02 Python
HTML5的video标签的浏览器兼容性增强方案分享
2016/05/19 HTML / CSS
世界上最大的在线汽车租赁预订平台:Rentalcars.com(支持中文)
2018/10/12 全球购物
法律专业自我鉴定
2013/10/03 职场文书
会议邀请函范文
2014/01/09 职场文书
《哪吒闹海》教学反思
2014/02/28 职场文书
租赁协议书
2015/01/27 职场文书
惹女朋友生气检讨书
2015/05/06 职场文书
体育教师教学随笔
2015/08/15 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
python - timeit 时间模块
2021/04/06 Python