文档章节

Javascript通过Name调用Function

顽Shi
 顽Shi
发布于 2014/06/10 14:27
字数 675
阅读 828
收藏 44

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

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

© 著作权归作者所有

共有 人打赏支持
顽Shi
粉丝 274
博文 81
码字总数 92387
作品 0
普陀
程序员
加载中

评论(15)

wskery001
wskery001
我只想说 少P IE,谷歌浏览都行,,不少P IE 就不行了,我试了试 确实如此
顽Shi
顽Shi

引用来自“王敏”的评论

反正 在 IE9是这样 原因是 [].slice.call(arguments) .splice(2) 在splice() 方法会直接对数组进行修改 所有NaN,
不过这么写可能确实不标准,改成你说的了
顽Shi
顽Shi

引用来自“王敏”的评论

反正 在 IE9是这样 原因是 [].slice.call(arguments) .splice(2) 在splice() 方法会直接对数组进行修改 所有NaN,
splice单参,表示只保留之前的元素.
顽Shi
顽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)
wskery001
wskery001
反正 在 IE9是这样 原因是 [].slice.call(arguments) .splice(2) 在splice() 方法会直接对数组进行修改 所有NaN,
wskery001
wskery001
IE9...大哥 splice() 必须的 参数 有2个, splice(2)肯定有问题
顽Shi
顽Shi

引用来自“王敏”的评论

我这 去掉P 就alert mvc 有P 就是 NaN..
你什么浏览器,我Google下用splice和slice都可以
wskery001
wskery001
我这 去掉P 就alert mvc 有P 就是 NaN..
顽Shi
顽Shi

引用来自“王敏”的评论

13多了 P 你没有看出来把!!!!!!!
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目
顽Shi
顽Shi

引用来自“王敏”的评论

13多了 P 你没有看出来把!!!!!!!
你都快愁死我了...
asp.net中调用javascript自定义函数的方法(包括引入JavaScript文件)总结

通常javascript代码可以与HTML标签一起直接放在前端页面中,但如果JS代码多的话一方面不利于维护,另一方面也对搜索引擎不友好,因为页面因此而变得臃肿;所以一般有良好开发习惯的程序员都会...

黄献
2012/11/04
0
0
iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge

iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge 转载:原地址 https://www.jianshu.com/p/e951af9e5e74 上一篇文章介绍了UIWebView 如何通过WebViewJavascriptBridge 来实现......

法斗斗
05/11
0
0
微信公众号开发纪要(4)-调用微信扫一扫功能

在微信公众号页面中调用微信扫一扫功能,就是调用微信JS-SDK。让JS-SDK完成调用摄像头扫描,然后我们将扫描结果进行业务操作。微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页...

pdzhsy
07/16
0
0
iframe 与主框架相互访问方法

1.同域相互访问 假设A.html 与 b.html domain都是localhost (同域) A.html中iframe 嵌入 B.html,name=myframe A.html有js function fMain() B.html有js function fIframe() 需要实现 A.ht......

lsjane
2015/08/20
0
0
JSPatch库, 一个Apple官方支持的实现在线更新iOS应用的库

简介 项目主页: https://github.com/bang590/JSPatch 示例下载: https://github.com/ios122/ios122 JSPatch 可以让你用 JavaScript 书写原生 iOS APP。只需在项目引入极小的引擎,就可以使用...

ios122
2015/11/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Bash重定向详解

Bash重定向详解 Bash的重定向指的是将命令的输入和输出导向不同地方,而不是默认的标准输入、标准输出和标准错误。Bash的重定向实际上是对标准输入、标准输出和标准错误的重置,进而将所需输...

小陶小陶
今天
3
0
EventBus原理深度解析

一、问题描述 在工作中,经常会遇见使用异步的方式来发送事件,或者触发另外一个动作:经常用到的框架是MQ(分布式方式通知)。如果是同一个jvm里面通知的话,就可以使用EventBus。由于Event...

yangjianzhou
今天
6
0
OpenCV图像处理实例:libuv+cvui显示摄像头视频

#include <iostream>#include <opencv2/opencv.hpp>#define CVUI_IMPLEMENTATION#include <cvui.h>extern "C"{#include <uv.h>}using namespace std;#define WINDOW_NAM......

IOTService
今天
3
0
openJDK之JDK9的String

1.openJDK8的String 先来看下openJDK8的String的底层,如下图1.1所示: 图1.1 底层上使用的是char[],即char数组 每个char占16个bit,Character.SIZE的值是16。 2.openJDK9中的String 图2.1...

克虏伯
今天
4
0
UEFI 模式下如何安装 Ubuntu 16.04

作者:知乎用户 链接:https://www.zhihu.com/question/52092661/answer/259583475 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 针对UEFI模式下安装U...

寻知者
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部