详解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 相关文章推荐
javascript+xml技术实现分页浏览
Jul 27 Javascript
javascript 模式设计之工厂模式学习心得
Apr 27 Javascript
只需20行代码就可以写出CSS覆盖率测试脚本
Apr 24 Javascript
JQuery中$(document)是什么意思有什么作用
Jul 21 Javascript
jQuery大于号(&gt;)选择器的作用解释
Jan 13 Javascript
深入解读JavaScript中的Iterator和for-of循环
Jul 28 Javascript
node.js cookie-parser 中间件介绍
Jun 06 Javascript
javascript数组拍平方法总结
Jan 20 Javascript
原生实现一个react-redux的代码示例
Jun 08 Javascript
3分钟了解vue数据劫持的原理实现
May 01 Javascript
layui的layedit富文本赋值方法
Sep 18 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
Oct 02 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原创论坛
2006/10/09 PHP
php模拟ping命令(php exec函数的使用方法)
2013/10/25 PHP
php中array_column函数简单实现方法
2016/07/11 PHP
ThinkPHP5+UEditor图片上传到阿里云对象存储OSS功能示例
2019/08/05 PHP
tp5递归 无限级分类详解
2019/10/18 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
javascript基础知识大全 便于大家学习,也便于我自己查看
2012/08/17 Javascript
Javascript 按位与运算符 (&amp;)使用介绍
2014/02/04 Javascript
Javascript基础教程之JavaScript语法
2015/01/18 Javascript
js获取当前日期前七天的方法
2015/02/28 Javascript
javascript实现输出指定行数正方形图案的方法
2015/08/03 Javascript
BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
2016/05/10 Javascript
JavaScript判断数组是否存在key的简单实例
2016/08/03 Javascript
高效的jQuery代码编写技巧总结
2017/02/22 Javascript
js手机号4位显示空格,银行卡每4位显示空格效果
2017/03/23 Javascript
node.js+express+mySQL+ejs+bootstrop实现网站登录注册功能
2018/01/12 Javascript
JavaScript实现的前端AES加密解密功能【基于CryptoJS】
2018/08/28 Javascript
Angular5中状态管理的实现
2018/09/03 Javascript
微信小程序页面渲染实现方法
2019/11/06 Javascript
js实现限定区域范围拖拉拽效果
2020/11/20 Javascript
python SQLAlchemy 中的Engine详解
2019/07/04 Python
Django CSRF跨站请求伪造防护过程解析
2019/07/31 Python
pytorch 状态字典:state_dict使用详解
2020/01/17 Python
QML实现钟表效果
2020/06/02 Python
CSS3结构性伪类选择器九种写法
2012/04/18 HTML / CSS
25道Java面试题集合
2013/05/21 面试题
2013的个人自我评价
2013/12/26 职场文书
《我的信念》教学反思
2014/02/15 职场文书
供货协议书范本
2014/04/22 职场文书
教师党员批评与自我批评
2014/10/15 职场文书
2014年团支部工作总结
2014/11/17 职场文书
新生入学欢迎词
2015/01/26 职场文书
支教个人总结
2015/03/04 职场文书
2015年幼儿园保育员工作总结
2015/04/23 职场文书
导游词之河姆渡遗址博物馆
2019/10/10 职场文书