的testFun
上下文是window
,這樣的行爲是完全正常的(調用testFun()
將在window
上下文中運行的話)。下面的行,testFun.call(myObj)
將導致所需的行爲(call
使用第一個參數作爲上下文或this
調用函數)。
請記住,你在自執行匿名塊(或立即函數)的閉包,這是不一樣的上下文。任何不作爲方法綁定到對象的函數的上下文始終是window
,無論它是否關閉。但是,它是關閉的,無論函數是在哪裏聲明的,所以如果你要在最後一個函數返回函數並將其分配給外部變量,alert(Name)
將顯示local data
而不是window data
,因爲testFun是在關閉中聲明的Name
等於local data
。
爲了進一步澄清:
// global closure scope, context (this) is window
Name = 'window data';
document.Name = 'current document data';
var testFun = (function(window, document) {
// immediate closure scope, context is still window
var Name = 'local data';
var myObj = {
Name: 'object data',
f: function() {
// myObj.f closure scope. immediate closure scope is available and superseeds global closure scope. context is myObj
alert(this.Name); // 'object data'
}
};
myObj.newFun = function() {
// newFun closure scope. immediate scope available and superseeds global scope. context is myObj
alert("Local scope " + Name + "\nObject Scope : " + this.Name); // outputs 'local data' (from immediate closure scope) and 'object data' (from myObj.Name)
}
function testFun() {
// testFun closure scope. immediate scope available and superseeds global scope. context is window
alert("Window Scope : " + window.Name + // 'window data'
"\nLocal Scope : " + Name + // 'local data (from immediate scope)
"\nObject Scope : " + this.Name + // 'window data' (remember this === window)
"\nCurrent document Scope : " + document.Name // 'current document data'
);
}
myObj.newFun();
//testFun(); // Promts see "Object Scope : window data", but suppose to be "Object Scope : local data"
// did not found the answer
testFun.call(myObj); // context for testFun is changed to myObj **for this call only**, this.Name === 'object data'
testFun.bind({
Name: "name injected"
})(); // context is the newly created object **for this call only**, this.Name === 'name injected'
return testFun;
})(window, document);
testFun(); // will output same as if called from within immediate function, because immediate scope survives immediate function's execution and is available to testFun (and superseeds global scope)
alert(Name); // 'window data' (global scope is still valid and is available to all statements declared outside immediate scope)
我想我明白了一下閱讀您的評論之後。自執行匿名塊的執行上下文是「窗口」。由於testFun()沒有在任何對象下定義,testFun()的執行上下文也是「窗口」。只要我在做testFun.call(myObj),它的執行上下文就是「myObj」。我對嗎? – 2014-10-18 18:03:46
是的,就是這樣:) – 2014-10-18 18:36:59
非常感謝你:) – 2014-10-18 19:30:27