详解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 EasyUI API 中文文档 - ProgressBar 进度条
Sep 29 Javascript
js防止页面被iframe调用的方法
Oct 30 Javascript
Jquery实现仿京东商城省市联动菜单
Nov 19 Javascript
详解javascript高级定时器
Dec 31 Javascript
JS使用正则表达式过滤多个词语并替换为相同长度星号的方法
Aug 03 Javascript
jQuery Easyui Tabs扩展根据自定义属性打开页签
Aug 15 Javascript
Angular实现购物车计算示例代码
Feb 21 Javascript
angular实现图片懒加载实例代码
Jun 08 Javascript
详解webpack 如何集成第三方js库
Jun 29 Javascript
vue mint-ui学习笔记之picker的使用
Oct 11 Javascript
js中arguments对象的深入理解
May 14 Javascript
关于JavaScript中异步/等待的用法与理解
Nov 18 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
用 PHP5 轻松解析 XML
2006/12/04 PHP
加强版phplib的DB类
2008/03/31 PHP
php中使用preg_replace函数匹配图片并加上链接的方法
2013/02/06 PHP
ThinkPHP连接Oracle数据库
2016/04/22 PHP
PHP中的print_r 与 var_dump 输出数组
2016/06/13 PHP
php foreach如何跳出两层循环(详解)
2016/11/05 PHP
JavaScript实现获取dom中class的方法
2015/02/09 Javascript
详解vue数据渲染出现闪烁问题
2017/06/29 Javascript
vue增删改查的简单操作
2017/07/15 Javascript
vue封装第三方插件并发布到npm的方法
2017/09/25 Javascript
mockjs,json-server一起搭建前端通用的数据模拟框架教程
2017/12/18 Javascript
npm全局模块卸载及默认安装目录修改方法
2018/05/15 Javascript
Vue使用vue-recoure + http-proxy-middleware + vuex配合promise实现基本的跨域请求封装
2019/10/21 Javascript
JS对日期操作封装代码实例
2019/11/08 Javascript
详解Vue串联过滤器的使用场景
2020/04/30 Javascript
微信小程序 wx:for 与 wx:for-items 与 wx:key的正确用法
2020/05/19 Javascript
详解ES6实现类的私有变量的几种写法
2021/02/10 Javascript
[02:11]DOTA2上海特级锦标赛主赛事第二日RECAP
2016/03/04 DOTA
Python跳出循环语句continue与break的区别
2014/08/25 Python
将Django使用的数据库从MySQL迁移到PostgreSQL的教程
2015/04/11 Python
Python中splitlines()方法的使用简介
2015/05/20 Python
详解Python中pyautogui库的最全使用方法
2020/04/01 Python
python中Ansible模块的Playbook的具体使用
2020/05/28 Python
Python字典fromkeys()方法使用代码实例
2020/07/20 Python
CSS3效果:自定义“W”形运行轨迹实例
2017/03/29 HTML / CSS
从一次项目重构说起CSS3自定义变量在项目的使用方法
2021/03/01 HTML / CSS
为什么如下的代码int a=100,b=100;long int c=a * b;不能工作
2013/11/29 面试题
自我鉴定范文300字
2013/10/01 职场文书
幼师求职信
2014/06/23 职场文书
教师党员个人整改措施材料
2014/09/16 职场文书
群众路线查摆问题整改措施思想汇报
2014/10/10 职场文书
主持人大赛开场白
2015/05/29 职场文书
心灵捕手观后感
2015/06/02 职场文书
教师节校长致辞
2015/07/31 职场文书
七年级之开学家长寄语35句
2019/09/05 职场文书
tomcat正常启动但网页却无法访问的几种解决方法
2022/05/06 Servers