Javascript中的匿名函数引用

Javascript中的匿名函数引用,javascript,dom-events,anonymous-function,mobile-website,Javascript,Dom Events,Anonymous Function,Mobile Website,我目前正在为我正在进行的一个项目构建一个非常简单的观察者类。我已经成功地实现了subscribe、unsubscribe和notify方法。当使用“常规”函数时,一切都完全按照预期工作(即:var f=function()) 但是,当我将一个匿名函数传递给subscribe方法,然后尝试通过传递“相同”的匿名函数取消订阅时,它(正如预期的那样)不会从数组中删除该函数(毕竟它们是不同的) 以下是我的订阅和取消订阅方法: this._subscribers = {}; subscribe: func

我目前正在为我正在进行的一个项目构建一个非常简单的观察者类。我已经成功地实现了subscribe、unsubscribe和notify方法。当使用“常规”函数时,一切都完全按照预期工作(即:
var f=function()

但是,当我将一个匿名函数传递给subscribe方法,然后尝试通过传递“相同”的匿名函数取消订阅时,它(正如预期的那样)不会从数组中删除该函数(毕竟它们是不同的)

以下是我的订阅和取消订阅方法:

this._subscribers = {};
subscribe: function(type, callback) {
    if ( isUndefined(this._subscribers[type]) ) {
        this._subscribers[type] = [];
    }
    this._subscribers[type].push(callback);
},
unsubscribe: function(type, callback) {
    if ( this._subscribers[type] instanceof Array ) {
        var index = this._subscribers[type].indexOf(callback);
        if ( index >= 0 ) {
            this._subscribers[type].splice(index, 1);
        }
    }
},
下面是我正在测试的代码:

var o = new gaf.events.Observable();
o.subscribe('testEvent', function(event) { alert('Got It!'); });
o.notify('testEvent');
// Correct alerts 'Got It!'
o.unsubscribe('testEvent', function(event) { alert('Got It!'); });
o.notify('testEvent')
// Incorrectly alerts 'Got It!'
我知道我可以使用一个对象(即:
\u订阅者[event]={}
),然后当某个对象订阅时,我可以添加一个等于回调的新属性和等于回调的值。这将导致Javascript将回调转换为字符串。然后,我可以使用该字符串查找它(前提是sub/unsub中传递的方法完全相同)

然而,这是一个移动项目,我对存储可能有数百个字符长的字符串非常谨慎,因为我们最终可能会有很多订户

还有其他的方法吗?是否有任何小的(小的,甚至)散列库可以用来散列函数的字符串值并将其用作属性?在数组(而不是实际回调)中存储回调的字符串值(以便与之进行比较)并对其使用
eval()
是否更好

编辑

首先,感谢大家的回复

关于“为什么还要传递匿名”函数的所有问题-

没有理由不使用命名函数。事实上,我同意大家的看法,命名函数将是更好的解决方案。我只是收集信息并寻找解决方案,以便构建一个尽可能最好地处理大多数场景的实现

另一个原因是,如果这个可观察类的用户(同事)将匿名函数传递给它,然后取消订阅,会发生什么情况。该功能实际上不会被取消订阅,因此不会被清除。我反对孤立数据:)


也许我应该问的另一个问题是,是否可以测试回调是否是匿名的?我假设没有,但问一下也无妨。

存储整个字符串没有错;过早优化是有害的

然而,这听起来是一个非常糟糕的主意。
如果有人更改了函数,但忘记更改未订阅的副本,代码将被微妙地破坏,而没有任何警告

相反,如果用户想要取消订阅,您可以要求用户将匿名函数存储在变量中。

或者,您可以向每个订阅者传递一个可选名称,然后以该名称取消订阅

使用观察器的客户端应该存储对函数的引用

   var obsCallback = function() {

   }
   o.subscribe('test', obsCallback);
   ....
   o.unsubscribe('test', obsCallback);

换句话说,保留对函数的引用…

传递匿名函数而不是命名函数的原因是什么,或者保留可用于以后取消订阅的引用是什么


或者,您可以允许一个可选的“id”参数,但这将需要不必要的复杂簿记以避免重复。

也许更好的解决方案是使用您的库修改代码

var f = function() { alert('Got It!'); };
o.subscribe('testEvent', f);
o.notify('testEvent');
o.unsubscribe('testEvent', f);
o.notify('testEvent');
您甚至可以从subscribe方法返回函数

var f = o.subscribe('testEvent', function() { alert('Got It!'); });
// ...

然后,如果您要为订阅的函数存储哈希或其他标识符,则调用代码对其不透明,这意味着您只需使用返回值取消订阅,库就会隐藏实现细节。

作为一个移动项目,我认为您不想通过复制匿名函数来浪费空间(一个用于订阅,一个用于取消订阅)。此外,您还需要哈希库的开销(空间和性能)。哈希库需要对函数进行“字符串化”,然后对其进行哈希。“字符串化”操作需要正确地使用空格。所有这些听起来都很头痛。我建议遵循将函数保存到变量或使用命名函数的最佳实践。感谢您的评论!这就是为什么我没有直接实现哈希函数的原因。移动设备上该过程的开销和复杂性你把我带走了。谢谢你的洞察力!我同意储存这根绳子是一个完全不好的主意。我只是把我对这件事的一些想法抛诸脑后:)