javascript 中的关键词 this 代指 执行上下文(Execution Contexts),函数做用域中的this,理解上来讲是指调用这个函数的对象。相信如下几个实验能够加深对this关键字的理解。javascript
全局做用域下的函数里面的this,显然等于全局对象windowhtml
function test(){ console.log(this === window) //true } test()
因此,显然,能够经过this,改变window里面的全局变量java
var global = "global" function test(){ this.global = "global2" } test() console.log(global)//global2
因此,若是你建立了一个构造函数,而后不当心调用了它,那么至关于你为全局对象赋值了,这个缺陷能够经过ES5里面的"use strict"
来解决。闭包
"use strict"; var global = "global" function test(){ console.log(this)//undefined this.global = "global2"//TypeError because 'this' undefined } test();
严格模式下,全局模式下的函数内部的this为undefined,而不会默认为windowapp
经过普通对象声明的函数this函数
var myobject = { foo : function(){ console.dir(this) //myobject } } myobject.foo()
foo里面的this指向调用foo的对象myobject,这个对象里面只有一个方法foo,所以咱们能够经过this操做 指向对象 里的其余值oop
var myobject = { v : 5, foo : function(){ this.v ++ console.log(this.v)//6 } } myobject.foo()
多层对象的状况下,this指向最近的一个对象,即谁直接调用这个函数,谁是thisthis
var myobject = { foo : { bar : function(){ console.dir(this)//foo } } } myobject.foo.bar()
以上状况this指向foo对象,那么咱们再考虑以下的状况code
var myobject = { foo : function(){ console.dir(this)//myobject var bar = function(){ console.dir(this)/*window "use strict" undefined*/ } bar() } } myobject.foo()
咱们能够发现,若是在foo函数里声明新的函数(闭包),好比绑定事件,settimeout里的匿名函数等状况,这里面的this会变为window(严格模式下undefined)。
形成这个错误的缘由是,bar()调用的时候,是全局对象window在调用的它,而不是经过myobject调用(换句话说myobject里面压根就没有bar),这种状况下若是要经过myobject调用bar须要用到call或applyhtm
var myobject = { foo : function(){ console.log(this)//myobject var bar = function(){ console.log(this) } bar.call(myobject)//myobject } } myobject.foo()
理解为,函数中的this,跟调用时的情形有关。
构造函数经过new来赋值情形也跟对象相似,好比
function testobject(){ this.kk = 6; this.dd = function(){console.log(this)}; } var fish = new testobject fish.dd(); /* [object Object] { dd: function (){window.runnerWindow.proxyConsole.log(this)}, kk: 6 } */
new
操做符会将this指向构造函数构造出来的对象
var myobject = { foo : function(){ console.log(this)//myobject document.body.onclick = function(){ console.dir(this)//[object HTMLBodyElement] } } } myobject.foo()
点击回调里的this指向点击对象
为避免this混乱,能够采用下面几种方法
var myobject = { foo : function(){ var that = this document.body.onclick = function(){ console.dir(that)//myobject } } } myobject.foo()
var myobject = { foo : function(){ var bar = function(){ console.log(this) } bar.call(myobject)//myobject } } myobject.foo()
var myobject = { v : 5, foo : function(){ var bar = function(){ console.log(++myobject.v)//直接修改myobject对象里的值 } bar(); } } myobject.foo()
http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
http://javascript.ruanyifeng.com/oop/basic.html
http://ryanmorr.com/understanding-scope-and-context-in-javascript/
http://stackoverflow.com/questions/9468055/what-does-new-in-javascript-do-anyway