详解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 相关文章推荐
Js切换功能的简单方法
Nov 23 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
Dec 03 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
Oct 23 Javascript
jquery动态加载select下拉框示例代码
Dec 10 Javascript
js函数模拟显示桌面.scf程序示例
Apr 20 Javascript
js判断浏览器是否支持html5
Aug 17 Javascript
Bootstrap每天必学之媒体对象
Nov 30 Javascript
Javascript数组Array方法解读
Mar 13 Javascript
javascript设计模式Constructor(构造器)模式
Aug 19 Javascript
jQuery实现加入收藏夹功能(主流浏览器兼职)
Dec 24 Javascript
详解vue项目中如何引入全局sass/less变量、function、mixin
Jun 02 Javascript
在Vue mounted方法中使用data变量详解
Nov 05 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
apache mysql php 源码编译使用方法
2012/05/03 PHP
php格式化日期和时间格式化示例分享
2014/02/24 PHP
php+ajax无刷新上传图片的实现方法
2016/12/06 PHP
php mysql数据库操作类(实例讲解)
2017/08/06 PHP
Dom加载让图片加载完再执行的脚本代码
2008/05/15 Javascript
理解Javascript_02_理解undefined和null
2010/10/11 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
2012/09/14 Javascript
js下将阿拉伯数字每三位一逗号分隔(如:15000000转化为15,000,000)
2014/06/02 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
jQuery获取剪贴板内容的方法
2016/06/16 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
jQuery简单实现对数组去重及排序操作实例
2017/10/31 jQuery
利用jquery如何从json中读取数据追加到html中
2017/12/01 jQuery
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
2018/09/12 Javascript
jquery.param()实现数组或对象的序列化方法
2018/10/08 jQuery
vue watch关于对象内的属性监听
2019/04/22 Javascript
轻松解决JavaScript定时器越走越快的问题
2019/05/13 Javascript
JS实现简单移动端鼠标拖拽
2020/07/23 Javascript
vue 判断元素内容是否超过宽度的方式
2020/07/29 Javascript
浅谈python中的getattr函数 hasattr函数
2016/06/14 Python
Python中利用xpath解析HTML的方法
2018/05/14 Python
python pandas消除空值和空格以及 Nan数据替换方法
2018/10/30 Python
Python初学者常见错误详解
2019/07/02 Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
2019/08/12 Python
python词云库wordcloud的使用方法与实例详解
2020/02/17 Python
Python新建项目自动添加介绍和utf-8编码的方法
2020/12/26 Python
英国百安居装饰建材网上超市:B&Q
2016/09/13 全球购物
新闻专业毕业生英文求职信
2014/03/19 职场文书
公司员工离职证明书
2014/10/04 职场文书
努力学习保证书
2015/02/26 职场文书
黄埔军校观后感
2015/06/10 职场文书
2019暑假阅读倡议书
2019/06/24 职场文书
Windows server 2012 配置Telnet以及用法详解
2022/04/28 Servers
python数字图像处理之图像自动阈值分割示例
2022/06/28 Python