详解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的一些特性和用法整理小结
Jan 13 Javascript
JS命名空间的另一种实现
Aug 09 Javascript
如何使用HTML5地理位置定位功能
Apr 27 Javascript
详细介绍jQuery.outerWidth() 函数具体用法
Jul 20 Javascript
四种参数传递的形式——URL,超链接,js,form表单
Jul 24 Javascript
js实现滚动条滚动到某个位置便自动定位某个tr
Jan 20 Javascript
Highcharts学习之数据列
Aug 03 Javascript
使用jquery给新生的th绑定hover事件的实例
Feb 10 Javascript
JS中如何实现Laravel的route函数详解
Feb 12 Javascript
在vue中实现简单页面逆传值的方法
Nov 27 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
Aug 09 jQuery
JavaScript变速动画函数封装添加任意多个属性
Apr 03 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代码(抓取网页中的邮箱地址)
2012/07/17 PHP
php使用gettimeofday函数返回当前时间并存放在关联数组里
2015/03/19 PHP
PHP的静态方法与普通方法用法实例分析
2019/09/26 PHP
laravel 5.3 单用户登录简单实现方法
2019/10/14 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
2020/02/03 PHP
一个选择最快的服务器转向代码
2009/04/27 Javascript
js 匿名调用实现代码
2009/06/19 Javascript
jquery构造器的实现代码小结
2011/05/16 Javascript
js 使用form表单select类实现级联菜单效果
2012/12/19 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
Angularjs注入拦截器实现Loading效果
2015/12/28 Javascript
javascript简单进制转换实现方法
2016/11/24 Javascript
vue实现a标签点击高亮方法
2018/03/17 Javascript
用POSTMAN发送JSON格式的POST请求示例
2018/09/04 Javascript
H5+C3+JS实现双人对战五子棋游戏(UI篇)
2020/05/28 Javascript
js实现飞机大战游戏
2020/08/26 Javascript
vue移动端下拉刷新和上滑加载
2020/10/27 Javascript
[03:37]2016完美“圣”典 风云人物:Mikasa专访
2016/12/07 DOTA
用python + openpyxl处理excel2007文档思路以及心得
2014/07/14 Python
Python写的英文字符大小写转换代码示例
2015/03/06 Python
python中的闭包用法实例详解
2015/05/05 Python
Python的Flask框架应用程序实现使用QQ账号登录的方法
2016/06/07 Python
python2.7 mayavi 安装图文教程(推荐)
2017/06/22 Python
浅谈python的输入输出,注释,基本数据类型
2019/04/02 Python
Python计算信息熵实例
2020/06/18 Python
python如何用matplotlib创建三维图表
2021/01/26 Python
JavaScript+Canvas实现自定义画板的示例代码
2019/05/13 HTML / CSS
美国精品家居用品网站:US-Mattress
2016/08/24 全球购物
美国第一个网上卖鞋零售商:OnlineShoes.com
2017/09/24 全球购物
澳大利亚宠物食品和药物在线:Jumbo Pets
2018/03/24 全球购物
Internet主要有哪些网络群组成
2015/12/24 面试题
幼儿园中班新学期寄语
2014/01/18 职场文书
七年级历史教学反思
2014/02/05 职场文书
环保专项行动方案
2014/05/12 职场文书
2015年行政管理人员工作总结
2015/10/15 职场文书
Centos环境下Postgresql 安装配置及环境变量配置技巧
2021/05/18 PostgreSQL