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 相关文章推荐
表单内同名元素的控制
Nov 22 Javascript
常用的javascript function代码
May 23 Javascript
巧用replace将文字表情替换为图片
Apr 17 Javascript
jQuery实现转动随机数抽奖效果的方法
May 21 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
May 11 Javascript
React实现双向绑定示例代码
Sep 19 Javascript
webpack配置的最佳实践分享
Apr 21 Javascript
js防刷新的倒计时代码 js倒计时代码
Sep 06 Javascript
js实现全选反选不选功能代码详解
Apr 24 Javascript
layui的select联动实现代码
Sep 28 Javascript
Vue2.X和Vue3.0数据响应原理变化的区别
Nov 07 Javascript
vue实现简易音乐播放器
Aug 14 Vue.js
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
PHP PDO函数库详解
2010/04/27 PHP
redis 队列操作的例子(php)
2012/04/12 PHP
PHP简单实现“相关文章推荐”功能的方法
2014/07/19 PHP
PHP中array_map与array_column之间的关系分析
2014/08/19 PHP
Laravel中扩展Memcached缓存驱动实现使用阿里云OCS缓存
2015/02/10 PHP
php metaphone()函数的定义和用法
2016/05/15 PHP
php中照片旋转 (orientation) 问题的正确处理
2017/02/16 PHP
一个简单的jQuery插件制作 学习过程及实例
2010/04/25 Javascript
TinyMCE 新增本地图片上传功能
2010/11/05 Javascript
jq选项卡鼠标延迟的插件实例
2013/05/13 Javascript
jquery分页插件jpaginate在IE中不兼容问题
2014/04/22 Javascript
浅谈jQuery中replace()方法
2015/05/13 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
2015/11/24 Javascript
说说AngularJS中的$parse和$eval的用法
2017/09/14 Javascript
vue-scroller记录滚动位置的示例代码
2018/01/17 Javascript
JS实现百度搜索接口及链接功能实例代码
2018/02/02 Javascript
Vue.js 事件修饰符的使用教程
2018/11/01 Javascript
CryptoJS中AES实现前后端通用加解密技术
2018/12/18 Javascript
Node绑定全局TraceID的实现方法
2019/11/14 Javascript
[05:04]完美世界携手游戏风云打造 卡尔工作室地图界面篇
2013/04/23 DOTA
Python读取Excel的方法实例分析
2015/07/11 Python
安装ElasticSearch搜索工具并配置Python驱动的方法
2015/12/22 Python
Android分包MultiDex策略详解
2017/10/30 Python
python实现换位加密算法的示例
2018/10/14 Python
解决python中无法自动补全代码的问题
2018/12/04 Python
python 格式化输出百分号的方法
2019/01/20 Python
详解python持久化文件读写
2019/04/06 Python
django中SMTP发送邮件配置详解
2019/07/19 Python
竞争性谈判邀请书
2014/02/06 职场文书
保护动物的标语
2014/06/11 职场文书
局领导领导班子四风对照检查材料
2014/09/27 职场文书
国庆庆典邀请函
2015/02/02 职场文书
生产实习心得体会范文
2016/01/22 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书
redis配置文件中常用配置详解
2021/04/14 Redis
手残删除python之后的补救方法
2021/06/26 Python