惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
小众软件
小众软件
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
Jina AI
Jina AI
博客园 - 【当耐特】
V
Visual Studio Blog
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
量子位
IT之家
IT之家
G
Google Developers Blog
V
V2EX
The GitHub Blog
The GitHub Blog
月光博客
月光博客
GbyAI
GbyAI

博客园 - temptation

【原】QuickTime安装时,提示CAB文件"QuickTime.cab"中找不到此文件 【原】MyEclipse8.5集成Tomcat7时启动错误:Exception in thread “main” java.lang.NoClassDefFoundError 【SQL精彩语句】按某一字段分组取最大(小)值所在行的数据 【原】VS2008错误:“未能正确加载包,使用 devenv /resetskippkgs 重新启用包加载”的解决 【原】安装adobe flash player,总是提示关闭IE的解决 【转】海量数据查询优化技巧 【原】JavaScript中Date对象的getYear()和getFullYear()的区别 【原】使用PE安装Win7/Win8心得 【原】win 7 屏幕旋转问题的解决 【原】VS2010使用HTML5智能提示 【转】json2.js的初步学习与了解 【原】C#二维数组的遍历 【转】从底层了解ASP.Net体系结构 【转】IIS5、IIS6、IIS7的ASP.net 请求处理过程比较 【转】函数式JavaScript编程指南 【SQL精彩语句】普通行列转换(完整版) 【原】《重构--改善既有代码的设计》书摘 【SQL精彩语句】分拆列值 【SQL精彩语句】合并列值
【转】javascript运行机制之this详解
temptation · 2014-02-04 · via 博客园 - temptation

this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要。而javascript的this又有区别于Java、C#等纯面向对象的语言,这使得this更加扑朔迷离,让人迷惑。

this使用到的情况:

1. 纯函数

2. 对象方法调用

3. 使用new调用构造函数

4. 内部函数

5. 使用call / apply

6.事件绑定

---------------------------------------------------------------

1. 纯函数

1 var name = 'this is window';  //定义window的name属性
2 function getName(){
3     console.log(this);    //控制台输出: Window  //this指向的是全局对象--window对象
4     console.log(this.name);  //控制台输出: this is window  /
5 }
6  
7 getName();

运行结果分析:纯函数中的this均指向了全局对象,即window。

2. 对象方法调用

 1 var name = 'this is window';  //定义window的name属性,看this.name是否会调用到
 2 var testObj = {
 3     name:'this is testObj',
 4     getName:function(){
 5         console.log(this);  //控制台输出:testObj   //this指向的是testObj对象
 6         console.log(this.name);  //控制台输出: this is testObj
 7     }
 8 }
 9 
10 testObj.getName();

运行结果分析:被调用方法中this均指向了调用该方法的对象。

3. 使用new调用构造函数

1 function getObj(){
2     console.log(this);    //控制台输出: getObj{}  //this指向的新创建的getObj对象
3 }
4 
5 new getObj();

运行结果分析:new 构造函数中的this指向新生成的对象。

4. 内部函数

 1 var name = "this is window";  //定义window的name属性,看this.name是否会调用到
 2 var testObj = {
 3     name : "this is testObj",
 4     getName:function(){
 5         //var self = this;   //临时保存this对象
 6         var handle = function(){
 7             console.log(this);   //控制台输出: Window  //this指向的是全局对象--window对象
 8             console.log(this.name);  //控制台输出: this is window  
 9             //console.log(self);  //这样可以获取到的this即指向testObj对象
10         }
11         handle();
12     }
13 }
14 
15 testObj.getName();

运行结果分析:内部函数中的this仍然指向的是全局对象,即window。这里普遍被认为是JavaScript语言的设计错误,因为没有人想让内部函数中的this指向全局对象。一般的处理方式是将this作为变量保存下来,一般约定为that或者self,如上述代码所示。

5. 使用call / apply

 1 var name = 'this is window';  //定义window的name属性,看this.name是否会调用到
 2 var testObj1 = {
 3     name : 'this is testObj1',
 4     getName:function(){
 5         console.log(this);   //控制台输出: testObj2  //this指向的是testObj2对象
 6         console.log(this.name);  //控制台输出: this is testObj2  
 7     }
 8 }
 9 
10 var testObj2 = {
11     name: 'this is testObj2'
12 }
13 
14 testObj1.getName.apply(testObj2);
15 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应该是最容易让人产生疑惑的地方,大部分的出错都源于此。

1 //页面Element上进行绑定
2   <script type="text/javascript">
3      function btClick(){
4 <span style="white-space:pre">        </span>console.log(this);  //控制台输出: Window  //this指向的是全局对象--window对象
5 <span style="white-space:pre">    </span> }
6   </script>
7   <body>
8     <button id="btn" onclick="btClick();" >点击</button>
9   </body>
 1 //js中绑定方式(1)
 2   <body>
 3     <button id="btn">点击</button>
 4   </body>
 5   <script type="text/javascript">
 6      function btClick(){
 7         console.log(this);  //控制台输出:<button id="btn">点击</button>  //this指向的是Element按钮对象
 8      }
 9      
10      document.getElementById("btn").onclick = btClick;
11      document.getElementById("btn").onclick;  
12   </script>
 1 //js中绑定方式(2)
 2  <body>
 3     <button id="btn">点击</button>
 4   </body>
 5   <script type="text/javascript">
 6      document.getElementById("btn").onclick = function(){
 7          console.log(this);  //控制台输出:<button id="btn">点击</button>  //this指向的是Element按钮对象
 8      }
 9      document.getElementById("btn").onclick;
10   </script>
 1 //js中绑定方式(3)
 2  <body>
 3     <button id="btn">点击</button>
 4   </body>
 5   <script type="text/javascript">
 6      function btClick(){
 7         console.log(this);  
 8      }
 9 
10      document.getElementById("btn").addEventListener('click',btClick); //控制台输出:<button id="btn">点击</button>  //this指向的是Element按钮对象把函数(方法)用在事件处理的时候。
11      document.getElementById("btn").attachEvent('onclick',btClick);  //IE使用,<span style="font-family: Arial, Helvetica, sans-serif;">控制台输出: Window  //this指向的是全局对象--window对象</span>
12  
13   </script>

运行结果分析:以上2种常用事件绑定方法,在页面Element上的进行事件绑定(onclick="btClick();"),this指向的是全局对象;而在js中进行绑定,除了attachEvent绑定的事件方法外,this指向的是绑定事件的Elment元素。