Javascript通过Name调用Function
博客专区 > 顽Shi 的博客 > 博客详情
Javascript通过Name调用Function
顽Shi 发表于4年前
Javascript通过Name调用Function
  • 发表于 4年前
  • 阅读 822
  • 收藏 44
  • 点赞 2
  • 评论 15

标题:腾讯云 新注册用户域名抢购1元起>>>   

摘要: 如何通过一个函数的名称,调用它?How to execute a function when I have its name ?

    最近在编写一个工具库的时候,要传递一个回一个回调函数,类似于这样:

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,就可以自动帮你注入相应的对象,找时间分析一下源码,哈. 

共有 人打赏支持
粉丝 270
博文 81
码字总数 92387
评论 (15)
wskery001
alert NaN!!!!!!!!!!!!!!
顽Shi

引用来自“王敏”的评论

alert NaN!!!!!!!!!!!!!!
运行没问题啊,代码最后一句是伪代码,不会没看出来吧...
顽Shi

引用来自“王敏”的评论

alert NaN!!!!!!!!!!!!!!
最后一句直接改为可运行的了
wskery001
var args = [].slice.call(arguments).slice(2);
wskery001
13多了 P 你没有看出来把!!!!!!!
顽Shi

引用来自“王敏”的评论

13多了 P 你没有看出来把!!!!!!!
你都快愁死我了...
顽Shi

引用来自“王敏”的评论

13多了 P 你没有看出来把!!!!!!!
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目
wskery001
我这 去掉P 就alert mvc 有P 就是 NaN..
顽Shi

引用来自“王敏”的评论

我这 去掉P 就alert mvc 有P 就是 NaN..
你什么浏览器,我Google下用splice和slice都可以
wskery001
IE9...大哥 splice() 必须的 参数 有2个, splice(2)肯定有问题
wskery001
反正 在 IE9是这样 原因是 [].slice.call(arguments) .splice(2) 在splice() 方法会直接对数组进行修改 所有NaN,
顽Shi

引用来自“王敏”的评论

IE9...大哥 splice() 必须的 参数 有2个, splice(2)肯定有问题
你也太详细你文档了,w3c的demo,自己运行看看 var arr = new Array(6) arr = "George" arr = "John" arr = "Thomas" arr = "James" arr = "Adrew" arr = "Martin" document.write(arr + "
") arr.splice(2) document.write(arr)
顽Shi

引用来自“王敏”的评论

反正 在 IE9是这样 原因是 [].slice.call(arguments) .splice(2) 在splice() 方法会直接对数组进行修改 所有NaN,
splice单参,表示只保留之前的元素.
顽Shi

引用来自“王敏”的评论

反正 在 IE9是这样 原因是 [].slice.call(arguments) .splice(2) 在splice() 方法会直接对数组进行修改 所有NaN,
不过这么写可能确实不标准,改成你说的了
wskery001
我只想说 少P IE,谷歌浏览都行,,不少P IE 就不行了,我试了试 确实如此
×
顽Shi
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: