详解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 相关文章推荐
greybox——不开新窗口看新的网页
Feb 20 Javascript
在次封装easyui-Dialog插件实现代码
Nov 14 Javascript
JavaScript代码简单实现求杨辉三角给定行的最大值
Oct 29 Javascript
jquery实现倒计时功能
Dec 28 Javascript
AngularJS ng-bind 指令简单实现
Jul 30 Javascript
Javascript中apply、call、bind的巧妙使用
Aug 18 Javascript
jquery编写日期选择器
Mar 16 Javascript
JS实现动态添加外部js、css到head标签的方法
Jun 05 Javascript
微信小程序从注册账号到上架(图文详解)
Jul 17 Javascript
使用vscode快速建立vue模板过程详解
Oct 10 Javascript
解决vue+router路由跳转不起作用的一项原因
Jul 19 Javascript
Element DateTimePicker日期时间选择器的使用示例
Jul 27 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实现redis数据库指定库号迁移的方法
2015/01/14 PHP
php上传文件并显示上传进度的方法
2015/03/24 PHP
PHP 微信扫码支付源代码(推荐)
2016/11/03 PHP
静态的动态续篇之来点XML
2006/08/15 Javascript
JavaScript 利用Cookie记录用户登录信息
2009/12/08 Javascript
控制input输入框中提示信息的显示和隐藏的方法
2014/02/12 Javascript
node.js中RPC(远程过程调用)的实现原理介绍
2014/12/05 Javascript
iframe里使用JavaScript控制主页转向的方法
2015/04/03 Javascript
coffeescript使用的方式汇总
2015/08/05 Javascript
基于jQuery实现select下拉选择可输入附源码下载
2016/02/03 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
详解vue2.0 transition 多个元素嵌套使用过渡
2017/06/19 Javascript
JS仿QQ好友列表展开、收缩功能(第一篇)
2017/07/07 Javascript
js截取字符串功能的实现方法
2017/09/27 Javascript
canvas轨迹回放功能实现
2017/12/20 Javascript
JavaScript选择排序算法原理与实现方法示例
2018/08/06 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
2019/09/21 jQuery
JavaScript利用键盘码控制div移动
2020/03/19 Javascript
微信小程序选择图片控件
2021/01/19 Javascript
[46:43]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#2LGD VS MVP.Phx第二局
2016/03/02 DOTA
Python实现给qq邮箱发送邮件的方法
2015/05/28 Python
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
2016/07/04 Python
使用Python读写及压缩和解压缩文件的示例
2016/07/08 Python
Python中一些不为人知的基础技巧总结
2018/05/19 Python
pytorch中nn.Conv1d的用法详解
2019/12/31 Python
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
全球航班旅行搜索网站:Cheapflights
2017/05/19 全球购物
巴西男士个人护理产品商店:SHOP4MEN
2017/08/07 全球购物
Shoes For Crews法国官网:美国领先的防滑鞋设计和制造商
2018/01/01 全球购物
彪马西班牙官网:PUMA西班牙
2019/06/18 全球购物
俄罗斯最大的在线珠宝大卖场:Nebo
2019/12/08 全球购物
渡河少年教学反思
2014/02/12 职场文书
国际经济与贸易专业大学生职业规划书
2014/03/01 职场文书
政风行风自查自纠报告
2014/10/21 职场文书
追悼会答谢词
2015/01/05 职场文书
个人工作违纪检讨书
2015/05/05 职场文书