详解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 相关文章推荐
鼠标移入移出事件改变图片的分辨率的两种方法
Dec 17 Javascript
jQuery中animate()方法用法实例
Dec 24 Javascript
jquery右下角自动弹出可关闭的广告层
May 08 Javascript
Jquery插件easyUi实现表单验证示例
Dec 15 Javascript
javascript执行环境及作用域详解
May 05 Javascript
AngularJS基础 ng-readonly 指令简单示例
Aug 02 Javascript
微信小程序获取循环元素id以及wx.login登录操作
Aug 17 Javascript
Bootstrap4如何定制自己的颜色和风格
Feb 26 Javascript
基于iScroll实现内容滚动效果
Mar 21 Javascript
详解Bootstrap 学习(一)入门
Apr 12 Javascript
微信小程序 scroll-view 实现锚点跳转功能
Dec 12 Javascript
vue项目接口域名动态获取操作
Aug 13 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生成带有雪花背景的验证码
2008/09/28 PHP
PHP中PDO连接数据库中各种DNS设置方法小结
2016/05/13 PHP
PHP使用curl制作简易百度搜索
2016/11/03 PHP
laravel使用数据库测试注意事项
2020/04/10 PHP
PHP7新特性
2021/03/09 PHP
Jquery 组合form元素为json格式,asp.net反序列化
2009/07/09 Javascript
js+css在交互上的应用
2010/07/18 Javascript
setTimeout的延时为0时多个浏览器的区别
2012/05/23 Javascript
javascript获取url上某个参数的方法
2013/11/08 Javascript
ECMAScript6块级作用域及新变量声明(let)
2015/06/12 Javascript
Javascript实现鼠标框选操作  不是点击选取
2016/04/14 Javascript
JavaScript将DOM事件处理程序封装为event.js 出现的低级错误问题
2016/08/03 Javascript
jquery.validate表单验证插件使用方法解析
2016/11/07 Javascript
BACKBONE.JS 简单入门范例
2017/10/17 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
2018/10/09 Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
2018/12/24 Javascript
基于Bootstrap和JQuery实现动态打开和关闭tab页的实例代码
2019/06/10 jQuery
浅谈vue中get请求解决传输数据是数组格式的问题
2020/08/03 Javascript
[33:42]LGD vs OG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python中实现php的var_dump函数功能
2015/01/21 Python
apache部署python程序出现503错误的解决方法
2017/07/24 Python
Python使用wget实现下载网络文件功能示例
2018/05/31 Python
python多进程提取处理大量文本的关键词方法
2018/06/05 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤
2020/08/07 Python
详解HTML5之pushstate、popstate操作history,无刷新改变当前url
2017/03/15 HTML / CSS
印尼旅游网站:via
2017/11/12 全球购物
巴西香水和化妆品购物网站:The Beauty Box
2019/09/03 全球购物
美国亚马逊旗下时尚女装网店:SHOPBOP(支持中文)
2020/10/17 全球购物
自我评价的正确写法
2013/09/19 职场文书
争论的故事教学反思
2014/02/06 职场文书
顶撞老师检讨书
2014/02/07 职场文书
新课培训心得体会
2014/09/03 职场文书
入党申请书格式
2019/06/20 职场文书
Python+Pillow+Pytesseract实现验证码识别
2022/05/11 Python
JavaScript前端面试组合函数
2022/06/21 Javascript