javascript运行机制之this详细介绍


Posted in Javascript onFebruary 07, 2014

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指向的是绑定事件的Elment元素。

Javascript 相关文章推荐
javascript dom 操作详解 js加强
Jul 13 Javascript
Javascript MVC框架Backbone.js详解
Sep 18 Javascript
JavaScript图片轮播代码分享
Jul 31 Javascript
JS面试题---关于算法台阶的问题
Jul 26 Javascript
jQuery动态增减行的实例代码解析(推荐)
Dec 05 Javascript
通过构造函数实例化对象的方法
Jun 28 Javascript
vuejs事件中心管理组件间的通信详解
Aug 09 Javascript
详解ionic本地相册、拍照、裁剪、上传(单图完全版)
Oct 10 Javascript
原生JS实现简单的倒计时功能示例
Aug 30 Javascript
vue分页器组件编写方法详解
Jun 28 Javascript
jquery多级树形下拉菜单的实例代码
Jul 09 jQuery
js 图片懒加载的实现
Oct 21 Javascript
jQuery获取当前对象标签名称的方法
Feb 07 #Javascript
JQuery与Ajax调用新浪API获取短网址的代码
Feb 07 #Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
Feb 07 #Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
Feb 07 #Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
Feb 07 #Javascript
Ajax提交与传统表单提交的区别说明
Feb 07 #Javascript
JQUERY 设置SELECT选中项代码
Feb 07 #Javascript
You might like
Ajax PHP 边学边练 之三 数据库
2009/11/26 PHP
destoon安全设置中需要设置可写权限的目录及文件
2014/06/21 PHP
php-redis中的sort排序函数总结
2015/07/08 PHP
php正则表达式验证(邮件地址、Url地址、电话号码、邮政编码)
2016/03/14 PHP
JavaScript中判断页面关闭、页面刷新的实现代码
2014/08/27 Javascript
浅谈javascript面向对象程序设计
2015/01/21 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
2015/08/06 Javascript
JS实现状态栏跑马灯文字效果代码
2015/10/24 Javascript
探寻JavaScript中this指针指向
2016/04/23 Javascript
js完整倒计时代码分享
2016/09/18 Javascript
两种简单的跨域方法(jsonp、php)
2017/01/02 Javascript
十大热门的JavaScript框架和库
2017/03/21 Javascript
VUE搭建手机商城心得和遇到的坑
2019/02/21 Javascript
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
2021/01/08 Vue.js
[06:16]第十四期-国士无双绝地翻盘之撼地神牛
2014/06/24 DOTA
[02:05]2014DOTA2西雅图邀请赛 老队长全明星大猜想谁不服就按进显示器
2014/07/08 DOTA
python装饰器使用方法实例
2013/11/21 Python
10款最好的Web开发的 Python 框架
2015/03/18 Python
python数据结构之图的实现方法
2015/07/08 Python
python中使用正则表达式的后向搜索肯定模式(推荐)
2017/11/11 Python
python生成不重复随机数和对list乱序的解决方法
2018/04/09 Python
Django rest framework实现分页的示例
2018/05/24 Python
python开发游戏的前期准备
2019/05/05 Python
利用python实现PSO算法优化二元函数
2019/11/13 Python
Python实现加密接口测试方法步骤详解
2020/06/05 Python
css3学习之2D转换功能详解
2016/12/23 HTML / CSS
html5 div布局与table布局详解
2016/11/16 HTML / CSS
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
英国男女奢华内衣和泳装购物网站:Figleaves
2017/01/28 全球购物
打架检讨书400字
2014/01/17 职场文书
关于抽烟的检讨书
2014/02/25 职场文书
介绍信的写法
2015/01/31 职场文书
酒店辞职书范文
2015/02/26 职场文书
实习员工转正的评语汇总,以备不时之需
2019/12/17 职场文书
教你修复 Win11应用商店加载空白问题
2021/12/06 数码科技
Redis官方可视化工具RedisInsight安装使用教程
2022/04/19 Redis