关于javascript中的this的真正理解方式。

来源:互联网 发布:多益网络的手游 编辑:程序博客网 时间:2024/06/05 05:20

很多同学不理解this的意义,网上也有各种讲解,但是都不太好理解,所以我用一句话总结了:
this完全等于其所在的function的声明处的父级object对象
表达式:object.function中的this===object

也就是说与声明方法的位置有关
可能还是不清楚,举个栗子说明:

全局方法中的this

定义:全局方法中的this为window对象

function f(){   return this; }f()===window; //true

说明:以上这个例子中的this是在方法f中,f是在全局声明的,所以其父级对象是window,所以有window.f()===window,也可以理解为window.f 中的this就是window

对象方法中的this

定义:某对象里以 键值对形式 声明的方法中的this为该对象。

var obj={     f:function(){         return this     }}obj.f()===obj; //true

以上这个例子中的this同样在方法f中,但是这次的声明方法f的位置是在父级对象obj中,而不是全局window,所以有obj.f()===obj,也可理解为obj.f中的this就是obj

所以我们可以分三步判断this的值:
1、this在哪个function中?
2、这个方法在哪里声明的?
3、声明处的父级object是哪个?

有了上面的例子,下面的例子就更好理解了。

var name='global';function f(){    console.log(this.global);}var obj={     name:'obj的name',     methods:function(){          f();          console.log(this.name);     }}obj.methods(); //输出: global obj的name

本例子中obj.methods执行时,先触发f的执行,这里输出的是 global,原因是this只与其所在方法的声明位置有关,和所在执行环境无关,而第二个输出的自然就是 obj的name。

局部/匿名方法中的this

定义:局部(或匿名)方法中的this为window

var name='global';var obj={     name:'obj的name',     methods:function(){         var partialFun=function(){             console.log(this.name)         }         partialFun();         return function(){             console.log(this.name)         }      }}obj.methods()(); //输出:global global

匿名和局部函数是特别的函数,他不能通过window.partialFun()来调用,但是默认其函数内部中的this为window对象。

以上所有的例子如果你能理解了,基本已经可以处理大部分this的应用了,但是有时候我想规定这个this必须是谁,这种情况下怎么办呢?

自定义this的指向

定义:bind方法会可以任意改变this的指向。

方法.bind(arg);//参数arg就是破坏这个规则的对象,他强制当前方法中的this===该参数arg

例:

var name='global'var obj={     name:'obj的name',     f1:function(){         console.log(this.name)     },     f2:function(){         console.log(this.name)     }.bind(this) }obj.f1();  //输出: obj的nameobj.f2();  //输出: global  

obj.f1中的this当然指的就是f1的父级对象,就是obj,所以this.name===obj.name,输出了 obj的name。
obj.f2方法用了bind(this),首先得判断这个参数this是谁?是window还是obj?答案是 window,由于this的位置处于f2方法外部,由此推论出 bind(window),所以f2中的this会变成我们规定的window对象,输出了global。

还有这样的

obj.f1.apply(this,[]);  //globalobj.f1.call(this,'');   //global

apply,call是在调用时改变当前方法中this的指向
bind是在声明时改变方法中this的指向

看似打脸的例子

var name = 'global'var obj = {    name : 'obj的name',    f : function(){        console.log(this.name);    }}var f = obj.f;f(); 

这个例子看起来比较特别,而且答案特别出乎意料地是 global,刚才不是还说好的与执行位置无关吗?这个怎么解释?
看好了,我执行的并不是obj.f,而是变量f,变量f的声明位置是全局,只是物理地址和obj.f是一致的,所以其中的this,就是window。

总结:
1、this的值与其执行方法的声明位置有关,与执行位置无关。
2、全局、匿名、局部方法中的this,默认为window对象。
3、自定义this的值可以用Function.bind(自定义值)实现。