javascript运行机制之this详细介绍

 这篇文章主要介绍了javascript运行机制之this,需要的朋友可以参考下

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元素。
 
 

时间: 2024-09-17 04:45:59

javascript运行机制之this详细介绍的相关文章

javascript运行机制之this详细介绍_基础知识

this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要.而javascript的this又有区别于Java.C#等纯面向对象的语言,这使得this更加扑朔迷离,让人迷惑. this使用到的情况:1. 纯函数2. 对象方法调用3. 使用new调用构造函数4. 内部函数5. 使用call / apply 6.事件绑定 1. 纯函数 复制代码 代码如下: var name = 'this is window';  //定义window的name属性  f

javaScript事件机制兼容【详细整理】_基础知识

[添加事件机制]  addEventListener  和  attachEvent [W3C] addEventListener('click' , function(){alert('Hello World')} ,false )  //W3C规范添加事件(IE8及以上不兼容):  第一个参数为事件类型 ,第二个为事件程序 ,第三个 false为事件冒泡,true为事件捕获 [IE] attachEvent('onclick',function(){alert('Hello World')}

从setTimeout谈JavaScript运行机制

前言 最近在看些JavaScript异步的东西,但是由于时间有限,才刚看了个头,不得不中途停止.为了方便日后查阅以备重拾,遂记录一点体会,如果能使得他人有所收获,那更是极好的.其实本文与异步并没有太大关系. 从setTimeout说起 众所周知,JavaScript是单线程的编程,什么是单线程,就是说同一时间JavaScript只能执行一段代码,如果这段代码要执行很长时间,那么之后的代码只能尽情地等待它执行完才能有机会执行,不像人一样,人是多线程的,所以你可以一边观看某岛国动作片,一边尽情挥洒汗

【朴灵评注】JavaScript 运行机制详解:再谈Event Loop

PS: 我先旁观下大师们的讨论,得多看书了~ 别人说的:"看了一下不觉得评注对到哪里去,只有吹毛求疵之感. 比如同步异步介绍,本来就无大错:比如node图里面的OS operation,推敲一下就可以猜到那是指同步操作(自然不走event loop了):至于watcher啥的,显然只是实现上的特色,即使用同一个queue实现也未尝不可" [原帖: http://www.ruanyifeng.com/blog/2014/10/event-loop.html 作者:阮一峰] 一年前,我写了

JavaScript 运行机制详解:再谈Event Loop

一年前,我写了一篇<什么是 Event Loop?>,谈了我对Event Loop的理解. 上个月,我偶然看到了Philip Roberts的演讲<Help, I'm stuck in an event-loop>.这才尴尬地发现,自己的理解是错的.我决定重写这个题目,详细.完整.正确地描述JavaScript引擎的内部运行机制.下面就是我的重写. 进入正文之前,插播一条消息.我的新书<ECMAScript 6入门>出版了(版权页,内页1,内页2),铜版纸全彩印刷,非常

JavaScript运行机制之事件循环(Event Loop)详解_javascript技巧

一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. JavaScript的单线程,与它的用途有关.作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM.这决定了它只能是单线程,否则会带来很复杂的同步问题.比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线

JavaScript event对象整理及详细介绍_javascript技巧

Event属性和方法: 1. type:事件的类型,如onlick中的click: 2. srcElement/target:事件源,就是发生事件的元素: 3. button:声明被按下的鼠标键,整数,1代表左键,2代表右键,4代表中键,如果按下多个键,酒把这些值加起来,所以3就代表左右键同时按下:(firefox中 0代表左键,1代表中间键,2代表右键) 4. clientX/clientY:事件发生的时候,鼠标相对于浏览器窗口可视文档区域的左上角的位置:(在DOM标准中,这两个属性值都不考虑

JavaScript中的闭包(Closure)详细介绍_javascript技巧

闭包是JavaScript中一个重要的特性,其最大的作用在于保存函数运行过程中的信息.在JavaScript中,闭包的诸多特性源自函数调用过程中的作用域链上.   函数调用对象与变量的作用域链   对于JavaScript中的每一次函数调用,JavaScript都会创建一个局部对象以储存在该函数中定义的局部变量:如果在该函数内部还有一个嵌套定义的函数(nested function),那么JavaScript会在已经定义的局部对象之上再定义一个嵌套局部对象.对于一个函数,其内部有多少层的嵌套函数

Javascript中的delete操作符详细介绍_基础知识

一.变量 说到javascript中的delete操作符,还是首先要搞清楚javascript中的变量和属性之间的关系. javascript中,变量和对象属性关系非常微妙,甚至可以很多时候会被等同起来,因为 javascript 在执行脚本之前会创建一个global对象,在浏览器中就是window对象,所有的全局变量都是这个global对象的属性,执行函数时也会创建一个activation对象,所有的局部变量都是这个activation对象的属性.这些可以大家可以去了解一下javascript