作为一个每天与JavaScript打交道的前端开发,虽然明知这样的问题没人看?,但还是忍不住要答一波以正视听。
既然题主强调是“形参(形式参数,formal parameters)”,那偶觉得回答说用arguments对象的肯定都不对。arguments是“实参(实际参数,actual parameters)”。
形参: 函数声明时指定的参数声明列表。实参: 函数调用时传递进来的参数列表。有了以上的概念,再来看题主的问题“javascript如何获取function的形参”。题主其实是想做类似反射的操作,给定一个函数变量,然后得到该函数定义时的参数声明列表。
首先,如果题主并非真的想拿到每个实参的详细信息,而是只需要实参个数,那么简单的使用length属性就可以了。这个方式,对箭头函数(arrow function)也是适用的。
如果题主真的想拿到每个实参的详细信息,那就比较有意思了,因为JavaScript里目前并没有提供直接的方式来实现这个操作,甚至最新的Reflect也帮不上什么忙。好在function的toString方法可以以字符串方式返回函数定义时的代码,这就提供了一个突破口(jiu ming dao cao),可以从function的定义里自行解析出参数列表。
而这也是流行的框架AngularJS实现基于形参的依赖注入(DI)的关键。这里直接给出AngularJS里的相关代码片段。
从代码中可以看到,该方法调用了toString拿到function的定义,使用正则来去除注释并提取形参列表。该实现也同时具备处理箭头函数的能力。
可以看到,这个方法相当的高效,而且兼容性也相当不错,即使参数中存在默认值、解构、可变参数等ES6的新语法,也不会出错,但也不会给出进一步的信息。
如果需要提取参数默认值、分析解构、或者判断是否为可变参数,则需要进一步的逐个分析,这里不再展开讨论。但有个相当简便的方法是,使用JavaScript语法分析器来解析,例如esprima,但可能会有较大的性能开销(可参考https://stackoverflow.com/questions/1007981/how-to-get-function-parameter-names-values-dynamically)。
另外,如果代码经过压缩,则这种方法就失效了。Angular.js的解决方法是在需要注入的地方,接收一个手动输入的数组作为函数的参数描述(也可以通过给函数设置静态属性提供注入信息),从而不受压缩的影响。但这样增加了开发人员的工作量(每个参数列表都需要重复两遍)。因此,有人开发了叫做ng-annotate的工具,可以集成的构建工具里自动为方法添加参数描述信息。
觉得不错请转发、点赞。
欢迎在评论区留下你的观点。
mysql比较日期,命令框连mysql,mysql 修改端口 命令,MySQL如何通过命令备份,redmine 附件mysql,数据库扩容 mysql