最近在编写一个工具库的时候,要传递一个回一个回调函数,类似于这样:
function a(){ // something } function b(str,callback){ callback(); } b("haha",a);
这样的写法比较常见了,不过还是需要传递参数.那能不能说不需要传递参数,只要知道存在这么一个叫做"a"的function,然后直接调用呢???必须能...,而且方法不止一种.
(1) 通过eval
坦白说我都不肯定现在搞Javascript的有几个人还记得eval,因为它强大的无以复加,所以名声实在太差了...如果你看过Javascript的书,基本上10本里有9本都会告诉你对待eval要慎用,不用,乃至禁用.
这里我得建议也是如果不是没有其他选择不要用eval,因为可能会出现你想象不到的问题...
(2) 通过window
通常情况下function定义在全局中,所以这个时候你通过window对象是可以得到所有你想要的东西的.
window["functionName"](arguments);
看起来不错,不是吗.不过问题是,现在尼玛还有几个人会把function写在全局下啊...这不是污染了全局变量,坑爹啊!!!
如果function那是挂载一个namespace下,这么调用还可不可以?比如:
window["My.Namespace.functionName"](arguments);
结果是令人振奋的!不可以!没有错,你没有看错,这么写实在太坑爹了,你见过谁写属性即用"[]"还用"."这么坑爹的,拜托你统一一下风格好不好...
window["My"]["Namespace"]["functionName"](arguments);
ok这样就没问题了,成功调用,赞一个,哦不,赞32个.
(3) 做的更好 - 英文叫do better
上面的简简单单一句话虽然成功实现了我们的理想,哦不,是目的.但是明显不够高大上啊,这代码一看就是屌丝写的,这哪行,高大上都要自己封装点什么的好不好!!!
关门,上代码:
function executeFunctionByName(functionName, context) { var args = [].slice.call(arguments).slice(2); // 这么写也可:var args = [].slice.call(arguments).splice(2); // 获取函数参数 var namespaces = functionName.split("."); var func = namespaces.pop(); for(var i = 0; i < namespaces.length; i++) { context = context[namespaces[i]]; } // 取得上下文 // 调用 return context[func].apply(this, args); }
运行一下,效果:
var aaa = { sss: function(str1,str2,str3){ alert(str1+str2+str3); } } executeFunctionByName("aaa.sss",window,"m","v","c"); // 或者如下 executeFunctionByName("sss", aaa, "m","v","c");
最后留个尾巴,写到这里突然想起来angular中高大上的依赖注入,只要你提供了name,就可以自动帮你注入相应的对象,找时间分析一下源码,哈.