关于侦听器中的范围

范围 指的是一个对象,函数在该对象中执行。该函数内的任何变量引用都被识别为该对象的属性。您可以使用 Delegate 类指定侦听器的范围。有关详细信息,请参阅委托事件

如上所述,可以通过调用 addEventListener() 向组件实例注册侦听器。该方法采用两个参数:一个是表示事件名称的字符串,另一个是对对象或函数的引用。下表列出了每个参数类型的范围:

侦听器类型

范围

Object

侦听器对象。

函数

广播事件的组件实例。

如果向 addEventListener() 传递一个对象,则会在该对象范围内调用指定给该对象的回调函数(或在该对象上定义的函数)。这意味着关键字 this 在回调函数内使用时是引用侦听器对象,如下所示:

var lo:Object = new Object();
lo.click = function(evt){
    // this 引用对象 lo
    trace(this);
}
myButton.addEventListener("click", lo);

但是,如果向 addEventListener() 传递一个函数,则会在调用 addEventListener() 的组件实例的范围内调用该函数。这意味着关键字 this 在该函数内使用时引用的是正在广播的组件实例。如果在类文件中定义该函数,这就会引发一个问题。您将无法通过预期路径访问该类文件的属性和方法,因为 this 并不指向该类的实例。要避免此问题,可使用 Delegate 类来将函数委托到正确的范围。请参阅委托事件

下面的代码说明了在类文件中传递给 addEventListener() 时函数的范围。要使用此代码,请将它复制到名为 Cart.as 的 ActionScript (AS) 文件中。使用一个 Button 组件 (myButton) 和一个 DataGrid 组件 (myGrid) 创建一个 Flash (FLA) 文件。在舞台上选择这两个组件,然后按 F8 将它们转换成名为 Cart 的新元件。在 Cart 元件的 Linkage 属性中,为该元件分配类 Cart

class Cart extends MovieClip {

    var myButton:mx.controls.Button;
    var myGrid:mx.controls.DataGrid;

    function myHandler(eventObj:Object){

    // 使用 eventObj 参数
    // 捕获事件类型。
        if (eventObj.type == "click"){

        /* 将 this 的值发送到"输出"面板中。
        因为 myHandler 函数并非在侦听器对象上
        定义,所以 this 是对 myHandler 所
        注册到的组件实例 (myButton) 
        的引用。同时,因为 this 并不引用
        Cart 类的实例,所以 myGrid 未定义。 
        */ 
            trace("this: " + this);
            trace("myGrid: " + myGrid);
        }
    }

    // 向 myButton 注册 myHandler 函数
    // 单击该按钮时,myHandler 将执行

    function onLoad():Void{
        myButton.addEventListener("click", myHandler);
    }
}