簡體   English   中英

Actionscript 3'這個'問題

[英]Actionscript 3 'this' question

有人可能會指出為什么以下代碼在第一種情況下失敗:

情況1

// In a constructor
this.gallery = new Gallery();
addChild(this.gallery);

this.gallery.addEventListener(GalleryEvent.WHATEVER, function(event:*) {
    // When this callback fires, there is a fail:
    // because there is no 'this.gallery'.
    this.gallery.someAction();
});

案例2

this.gallery.addEventListener(GalleryEvent.WHATEVER, function(event:*) {
    // This works fine
    gallery.someAction();
})

在這種情況下,是否有關this用法的規則?

這是因為“范圍鏈”。 在ActionScript 3(符合ECMAScript - JavaScript具有下面描述的相同行為)中,有一個內置的“places”列表,用於解析任何名為變量的命名變量。 例如,當在類的“普通”方法中時,范圍鏈看起來像這樣:

  • 當前實例對象(與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看起來像這樣(下面的第一個范圍是將要檢查的第一個范圍):

  • 函數f()一個實例,包含變量localvarinnerfunc
  • C類的當前實例
  • C
  • 全球范圍

重要的是要意識到當代碼行var innerfunc:Function = function()...執行時,它會動態創建Function對象,並動態設置其范圍鏈。 例如,假設你有這個(令人困惑的)代碼,給定一個參數an_arg ,它返回一個Function,當被調用時,它將打印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();
})

我可以永遠繼續這個主題 - 我發現它很吸引人:-)

因為你傳遞了這個函數function(event:*) ,這意味着它在該范圍內執行。

所以當它試圖尋找this它正在尋找event.gallery.someAction();

當你使用gallery ,它會嘗試在全局變量列表中找到它。

驗證這一點的一種方法是添加一個跟蹤(this)並查看會發生什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM