(AS3)使用闭包给事件监听附带参数

情景再现:有5个按钮,变量名分别是btn1~btn5,需求就是需要在点击的时候知道到底点了第几个按钮,也就是需要获取到btnx中的x(那个文本框是infoTxt),看下面:


简单的做法:

for (var i:int = 1; i <= 5; ++i)
{
    this["btn"+i].addEventListener(MouseEvent.CLICK, onClick);
}
function onClick(e:Event):void
{
    var name_:String = e.target.name;
    var index:int = int(name_.substr(name_.length - 1 , 1));
    infoTxt.text="点击了"+index+"号按钮";
}
function dispose():void
{
    for (var i:int = 1; i <= 5; ++i)
    {
        this["btn"+i].removeEventListener(MouseEvent.CLICK, onClick);
    }
}

很明显这样已经达到了想要的功能,但觉得这样的代码针对性太强,有可能我的按钮数量达到了2位数以上,那substr是不是要指定len为2呢?或者觉得这样写不够高端。。(很蛋疼是不是~)

为了简化代码,闭包很适时的出现在了我的脑海中,我们只要把 i 当成一个 upvalue ,这样就可以把这个值保存起来,在调用的时候直接拿参数就OK,看代码:

var listenerList:Array = [];
for (var i:int = 1; i <= 5; ++i)
{
    var f:Function = onClick(i);
    this["btn"+i].addEventListener(MouseEvent.CLICK, f);
    listenerList.push({elem:this["btn"+i],eventType:MouseEvent.CLICK,func:f});
}
function onClick(i_:int):Function
{
    return function(e:Event):void
    {
        infoTxt.text="点击了"+i_+"号按钮";
    }
}
function dispose():void
{
    for each (var obj:Object in listenerList)
    {
        obj.elem.removeEventListener(obj.eventType, obj.func);
    }
}

在事件监听的地方,使用闭包传递了一个 i 进去,返回了一个匿名方法,当然为了移除监听,我们需要把这个方法一起保存起来以便销毁。


当然两种方法都是可以解决问题的,能解决问题的方法都是好方法。

第一种方法甚至更简洁方便,不过多使用不同的技巧去实现功能需求对编程的能力增长还是很有意义的。

原文地址:https://www.cnblogs.com/bluesea-flash/p/3319238.html