日期:2014-05-16  浏览次数:20341 次

让Javascript函数的注册 - 调用 - 销毁机制更简洁易用

比较常见的一种机制是,定义一个Util对象,再定义它的add,remove,call方法,示例如下:

window.Util = {
    _fns : [],
    add : function (fn){
        return this._fns.push(fn);
    },
    remove : function (index){
        delete this._fns.push(index-1);
    },
    invoke : function (index){
        return this._fns[index].apply(window, Array.prototype.slice.call(arguments,1));
    }
};

// 注册
var fnId = Util.add( function( msg ) {
        alert( msg );
    } );

// 调用
Util.invoke(fnId, 'Hello, World' ); //-> 'Hello, World';

// 销毁
Util.remove(fnId);
这种方法虽然也不复杂,但是我觉得还是不够简练。CKEditor里用的方式是写在闭包里,把_fns藏起来了,但使用方式还是差不多,要Util.addFunction(), Util.removeFunction(), Util.callFunction()。

我写了一个更简练的,直接用Util()来调用。代码如下:

//把Util在闭包里进行定义
( function() {
var fns = [],ta;
window.Util = function (a){
    ta=typeof a;
    if(ta==='number'){
        if(a>0){
            if(fns[a-1]){
                return fns[a-1].apply(window, Array.prototype.slice.call(arguments,1));
            }
        }else{
            delete fns[-a-1];
        }
    }else if(ta==='function'){
        return fns.push(a);
    }
};
}());

// 注册
var fnId = Util( function( msg ) {
        alert( msg );
    } );

// 调用
Util( fnId, 'Hello, World' ); //-> 'Hello, World';

// 销毁,在id前面加上负号,既省事,也有语义
Util( - fnId);

// 销毁后调用,无效果
Util( fnId, 'Hello, World' );

通过这样的机制,最大程度简化了注册-调用-销毁的使用。

记得jQuery的万能$不?思路是一致的,我们要:写的更少,做的更多