在此,我假设您已经在运用Javascript中的类概念,假设您还了解OOP中的this.
还是习惯从实例来分析:
var someObject = {};
function someMethod(){
alert((this==window)+','+(this==someObject));
}
someObject.someMethod = someMethod;
someMethod();//true,false
someObject.someMethod();//false,true
上面的代码是定义了一个function和一个对象,并指定对象的某个属性为那个function;
在执行方法时我们知道,可以通过someObject.someMethod()这样调用,也可以通过someMethod()这样直接调用;
归根结底,这两种调用方式都能找到相应内存中的function-someMethod(有名方法),并执行。
但由于this在Javascript中的特殊性,这两种调用方式的输出却截然不同,前者返回false,true,而后者返回true,false,why?
网上有很多描述,我在此以我的理解作一个直白的描述,在需要JS处理机区分this时,方法由谁调用,则this表示谁。(之后会说明不需要JS处理机区分的情况)
someObject.someMethod()调用者为someObject,所以this==someObject返回true;
someMethod()呢?对window有所理解的人应该知道,Javascript页面级的作用域为window,即缺省有名对象都相当于window的一个属性,如定义var a;相当于指定window.a属性,定义function b同样相当于指定window.b属性。所以someMethod()的调用相当于window.someMethod()调用,调用者为window,所以this==window返回true;
若是只有这样,可能大家还是比较容易理解,在Javascript中还存在两个特殊方法,Function.call和Function.apply。
这两个方法的调用者为someFunction,参数分别为:
call(oCaller,arg1,arg2,...)
apply(oCaller,[arg1,agr2,...])
这两个方法可以显式的告诉JS处理机,执行someFunction中的this对象为我的第一个参数oCaller,这也就是我之前提到的不需要JS处理机区分的情况;
有兴趣的同学可以试运行以下的实例:
var someObject = {};
var someObject2 = {};
function someMethod(){
alert((this==window)+','+(this==someObject)+','+(this==someObject2));
}
someObject.someMethod = someMethod;
someMethod();//true,false,false
someObject.someMethod();//false,true,false
someMethod.apply(someObject);//or call//false,true,false
someMethod.apply(someObject2);//false,false,true
还有一种特殊情况,new操作符处理函数,new操作符会创建一个新对象,将this指向这个新对象,然后进行操作,所以其中的this不表示任何已知句柄的对象,而是一个新的匿名对象,通过赋值语句可以指定给某个变量或者对象属性上,在此不再多作蛰述,试运行以下示例;
var someObject = {};
function ClassA(){
alert((this==window)+','+(this==someObject));
this.someAttr = 'someAttr';
}
someObject = new ClassA();//false,false
alert(someObject.someAttr);//someAttr