详解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调用WebService的实现代码
Jun 19 Javascript
使用原生js实现页面蒙灰(mask)效果示例代码
Jun 20 Javascript
JS实现鼠标经过好友列表中的好友头像时显示资料卡的效果
Jul 02 Javascript
javascript实现动态标签云
Oct 16 Javascript
给angular加上动画效遇到的问题总结
Feb 17 Javascript
JS组件Bootstrap ContextMenu右键菜单使用方法
Apr 17 Javascript
实例讲解Jquery中隐藏hide、显示show、切换toggle的用法
May 13 Javascript
浅析JavaScript中作用域和作用域链
Dec 06 Javascript
Vue ElementUi同时校验多个表单(巧用new promise)
Jun 06 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
Sep 20 jQuery
vue input实现点击按钮文字增删功能示例
Jan 29 Javascript
vue-openlayers实现地图坐标弹框效果
Sep 24 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
人大复印资料处理程序_输入篇
2006/10/09 PHP
一步一步学习PHP(6) 面向对象
2010/02/16 PHP
php图片处理:加水印、缩略图的实现(自定义函数:watermark、thumbnail)
2010/12/02 PHP
第4章 数据处理-php字符串的处理-郑阿奇(续)
2011/07/04 PHP
php创建session的方法实例详解
2015/01/27 PHP
jQuery获取json后使用zy_tmpl生成下拉菜单
2015/03/27 PHP
PHP随手笔记整理之PHP脚本和JAVA连接mysql数据库
2015/11/25 PHP
jquery 学习笔记 传智博客佟老师附详细注释
2020/09/12 Javascript
javascript 面向对象编程基础:封装
2009/08/21 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
jQuery学习笔记之2个小技巧
2015/01/19 Javascript
JavaScript数组操作函数汇总
2016/08/05 Javascript
Web性能优化系列 10个提升JavaScript性能的技巧
2016/09/27 Javascript
js中json处理总结之JSON.parse
2016/10/14 Javascript
为什么要使用Vuex的介绍
2019/01/19 Javascript
Vue简单实现原理详解
2020/05/07 Javascript
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
Vue实现图书管理小案例
2020/12/03 Vue.js
详解在Python程序中解析并修改XML内容的方法
2015/11/16 Python
Python中异常重试的解决方案详解
2017/05/05 Python
Python字符串通过'+'和join函数拼接新字符串的性能测试比较
2019/03/05 Python
python matplotlib库直方图绘制详解
2019/08/10 Python
python opencv实现证件照换底功能
2019/08/19 Python
Django框架 Pagination分页实现代码实例
2019/09/04 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
2020/03/01 Python
python实现图片,视频人脸识别(dlib版)
2020/11/18 Python
美国二手奢侈品寄售网站:TheRealReal
2016/10/29 全球购物
澳大利亚最大的网上油画销售画廊:Direct Art Australia
2018/04/15 全球购物
大学校庆邀请函
2014/01/11 职场文书
降消项目实施方案
2014/03/30 职场文书
2014企业领导班子四风对照检查材料思想汇报
2014/09/17 职场文书
2014年变电站工作总结
2014/12/19 职场文书
行政助理岗位职责
2015/02/10 职场文书
教师党员自我评价2015
2015/03/04 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
Python爬虫入门案例之爬取二手房源数据
2021/10/16 Python