這是因爲「範圍鏈」。在ActionScript 3中(與ECMAScript兼容 - JavaScript具有下述相同的行爲),有一個內置的「位置」列表,用於解析任何命名變量,稱爲作用域鏈。例如。當在一個類的一個「正常」的方法,該作用域鏈看起來像這樣:
- 當前實例對象(同
this
)
- 類對象(用於訪問靜態變量)
- 全局範圍(用於訪問全局變量,例如
Math
)
但是,當你在一個匿名內部功能,範圍鏈具有在頂部一個條目,表示在範圍上在該點的方法匿名功能的時間離子是創建的。因此,例如,假設你有這樣的代碼:
class C {
var membervar:int;
function f() {
var localvar:int;
var innerfunc:Function = function() {
// what is on the scopechain here?
};
innerfunc();
}
}
在這種情況下,當你的,說:「什麼是對的scopechain這裏」時,scopechain看起來像這樣(下面是第一個範圍的行將要檢查第1名):功能f()
的
- 一個實例,用變量
localvar
和innerfunc
- 類的當前實例
C
- ŧ他類
C
- 全球範圍
認識到這一點很重要,當代碼var innerfunc:Function = function()...
執行行,它是動態創建的功能對象,和設置在飛行中的作用域鏈。因此,例如,假設你有這個(混亂)的代碼,其中,有一個參數an_arg
,返回該函數被調用時,將打印an_arg的價值:
function f(an_arg:int):Function {
return function():void {
trace(an_arg);
}
}
通過調用返回到f()
每個功能都有它自己的作用域鏈,指向f()
的不同實例。所以:
var func1:Function = f(3);
var func2:Function = f(4);
func1(); // prints 3
func2(); // prints 4
常見的方式,以避免這個問題,如果你真的想引用this
在內部函數,而不是依賴於作用域鏈的法寶,是建立在所謂的self
一個臨時變量外功能 - 在你的示例代碼的情況下,它應該是這樣的:
var self = this;
this.gallery.addEventListener(GalleryEvent.WHATEVER, function(event:*) {
// This works fine
self.gallery.someAction();
})
我能在這個問題上永遠持續下去 - 我覺得很有意思:-)
嘗試添加監聽* *沒有**使用匿名功能。 – 2011-01-19 00:49:28