我有一个基于 apache 的 Web 应用程序。php、js 和 jquery。一切正常。
在客户端,有一个 JS/jquery 中的小库,提供一些通用的列表处理方法。过去,我使用回调来处理那些方法必须略有不同的少数问题。这样我就可以为应用程序的不同部分重用列表处理、对话框处理等方法。然而,最近我在进入图书馆时不得不处理的回调数量增加了,我正在尝试重新设计:
我没有将所有回调指定为函数参数,而是在库中创建了一个中央目录对象。应用程序的每个模块在初始化时将其自己的回调变体注册到该目录中。在运行时,这些方法会在该目录中查找所需的回调,而不是期望在其参数列表中指定它。这清理了很多东西。
但是,我仍然无法摆脱一件事:我需要一个参数(我称之为上下文,模式可能是另一个术语),方法使用该参数在目录中查找所需的回调。这个上下文必须传递给所有方法。当然比到处指定的各种不同的回调要好,但我想知道我是否可以摆脱最后一个。但是,如果不是作为方法参数,我在哪里指定该上下文?我对 JS 和 jquery 很陌生,所以我没有找到解决这个问题的方法。显然我不想使用全局变量,坦率地说,我怀疑我是否可以简单地将上下文存储在单个变量中,因为由于所有事件处理程序和外部影响,方法可能会同时在不同的上下文中调用时间,或者至少是交错的。所以我想我需要更接近函数堆栈的东西。也许我可以简单地将上下文对象推送到堆栈并从需要知道的库层中读取它?当我再次离开图书馆时,该对象将被删除。当然也存在其他方法。
这里有这么多经验丰富的编码人员,当然可以给新手一个简短的提示,一个导致想法的起点,如何实现这一点。这种事情“通常”是如何完成的?
我试了一会儿,探索arguments.callee.caller
层次结构。我想也许我可以在调用函数中设置一个原型成员,然后,当执行进一步向下时,我可以简单地向上遍历调用堆栈,直到找到持有该属性的调用者并将该值用作上下文。然而,我也看到正在进行的讨论揭示了两件事:1.)arguments.callee
似乎已经贬值,2.)它似乎真的很贵。所以这是不行的。
我还阅读了有关 Function.caller 替代方案的信息(它似乎没有被贬低而且效率更高,但是直到现在我还没有探索这条线索......
正如当前所写的那样,通过在函数调用中指定一个附加参数来简单地传递上下文/模式。它带有一个唯一的字符串,在查阅目录时用作键。所以像这样的东西(不是复制的,而是作为原始示例编写的):
<!-- callbacks -->
callback_inner_task_base:function(arg1,arg2){
// do something with args
}
callback_inner_task_spec:function(arg1,arg2){
// do something with args
}
<!-- catalog -->
Catalog.Callback:function(context,slot){
// some plausibility checks...
return Catalog[context][slot];
}
Catalog.base.slot=callback_inner_task_base;
Catalog.spec.slot=callback_inner_task_spec;
<!-- callee -->
do_something:function(arg1,arg2,context){
...
// callback as taken from the catalog
Catalog.Callback(callback,'inner_task')(arg1,arg2);
...
}
<!-- caller -->
init:function(...){
...
do_something('thing-1',thing-2','base');
do_something('thing-1',thing-2','spec');
...
}