Actionscript 3'这个'问题

Yip*_*Yay 2 flash actionscript this actionscript-3

有人可能会指出为什么以下代码在第一种情况下失败:

情况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();
});
Run Code Online (Sandbox Code Playgroud)

案例2

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

this在这种情况下是否有关于使用的规则?

Mik*_*rty 6

这是因为"范围链".在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,当你是"在这里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);
    }
}
Run Code Online (Sandbox Code Playgroud)

调用返回的每个函数f()都有自己的作用域链,指向不同的实例f().所以:

var func1:Function = f(3);
var func2:Function = f(4);

func1(); // prints 3
func2(); // prints 4
Run Code Online (Sandbox Code Playgroud)

避免这个问题的常用方法是,如果你真的想this在内部函数中引用而不是依赖于作用域链的魔力,那就是创建一个self在外部函数中调用的临时变量- 在你的示例代码的情况下,它看起来像这样:

var self = this;
this.gallery.addEventListener(GalleryEvent.WHATEVER, function(event:*) {
    // This works fine
    self.gallery.someAction();
})
Run Code Online (Sandbox Code Playgroud)

我可以永远继续这个主题 - 我发现它很吸引人:-)