详解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代码优化 事件委托篇
Nov 01 Javascript
Javascript Web Slider 焦点图示例源码
Oct 10 Javascript
简单的js图片轮换代码(js图片轮播)
May 06 Javascript
javascript学习笔记_浅谈基础语法,类型,变量
Sep 19 Javascript
easyui tree带checkbox实现单选的简单实例
Nov 07 Javascript
深入理解node.js之path模块
May 03 Javascript
jQuery 开发之EasyUI 添加数据的实例
Sep 26 jQuery
详解javascript 正则表达式之分组与前瞻匹配
May 30 Javascript
压缩Vue.js打包后的体积方法总结(Vue.js打包后体积过大问题)
Feb 03 Javascript
Element的el-tree控件后台数据结构的生成以及方法的抽取
Mar 05 Javascript
JQuery+drag.js上传图片并且实现图片拖曳
Nov 18 jQuery
JavaScript仿京东轮播图效果
Feb 25 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实现的九九乘法口诀表简洁版
2014/07/28 PHP
PHP多进程编程之僵尸进程问题的理解
2017/10/15 PHP
thinkphp5实现微信扫码支付
2019/12/23 PHP
改版了网上的一个js操作userdata
2007/04/27 Javascript
css值转换成数值请抛弃parseInt
2011/10/24 Javascript
Javascript基础知识(三)BOM,DOM总结
2014/09/29 Javascript
探讨JavaScript语句的执行过程
2016/01/28 Javascript
Boostrap模态窗口的学习小结
2016/03/28 Javascript
jQuery中的基本选择器用法学习教程
2016/04/14 Javascript
react性能优化达到最大化的方法 immutable.js使用的必要性
2017/03/09 Javascript
node.js平台下的mysql数据库配置及连接
2017/03/31 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
vue+iview+less+echarts实战项目总结
2018/02/22 Javascript
Vue前端开发规范整理(推荐)
2018/04/23 Javascript
JavaScript设计模式之原型模式分析【ES5与ES6】
2018/07/26 Javascript
mocha的时序规则讲解
2019/02/16 Javascript
JS检索下拉列表框中被选项目的索引号(selectedIndex)
2019/12/17 Javascript
vue使用svg文件补充-svg放大缩小操作(使用d3.js)
2020/09/22 Javascript
jQuery列表动态增加和删除的实现方法
2020/11/05 jQuery
[46:50]Liquid vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python读大数据txt
2016/03/28 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
Python爬虫实现抓取京东店铺信息及下载图片功能示例
2018/08/07 Python
实例讲解Python中浮点型的基本内容
2019/02/11 Python
python爬虫 正则表达式解析
2019/09/28 Python
Python装饰器原理与基本用法分析
2020/01/07 Python
python rsa-oaep加密的示例代码
2020/09/23 Python
使用Python Tkinter实现剪刀石头布小游戏功能
2020/10/23 Python
日本酒店、民宿、温泉旅馆、当地旅行团中文预订:e路东瀛
2019/12/09 全球购物
数控加工专业毕业生自荐信
2013/09/27 职场文书
理财投资建议书
2014/03/12 职场文书
保密工作责任书
2014/04/16 职场文书
仓库统计员岗位职责
2015/04/14 职场文书
2015年党员个人工作总结
2015/05/13 职场文书
入党介绍人意见范文
2015/06/01 职场文书
少年雷锋观后感
2015/06/10 职场文书