考虑下面代码:
var MyObject = function() {}MyObject.prototype.whoAmI = function() {console.log(this === window ? "window" : "MyObj");
};var obj = new MyObject();现在,为了操作方便,我们创建一个对whoAmI方法的引用,这样通过whoAmI()而不是更长的obj.whoAmI()来调用。
var whoAmI = obj.whoAmI;为了确保没有问题,我们把 whoAmI 打印出来看一下:
console.log(whoAmI);输出:
function () {console.log(this === window ? "window" : "MyObj");
}Ok,看起来没啥问题。
接着,看看当我们调用obj.whoAmI() 和 whoAmI() 的区别。
obj.whoAmI();  // Outputs "MyObj" (as expected)
whoAmI();      // Outputs "window" (uh-oh!)什么地方出错了?当我们进行赋值时 var whoAmI = obj.whoAmI,新的变量whoAmI被定义在全局命名空间。结果,this的值是 window,而不是 MyObject 的 obj 实例!
因此,如果我们真的需要为一个对象的现有方法创建一个引用,我们需要确保在该对象的名字空间内进行,以保留 this值。一种方法是这样做:
var MyObject = function() {}MyObject.prototype.whoAmI = function() {console.log(this === window ? "window" : "MyObj");
};var obj = new MyObject();
obj.w = obj.whoAmI;   // Still in the obj namespaceobj.whoAmI();  // Outputs "MyObj" (as expected)
obj.w();       // Outputs "MyObj" (as expected)