目的是构建一个包装器,以提供一种一致的方法来调用各种脚本主机上具有可变 arity 的 native 函数 - 以便脚本可以在浏览器以及 Windows 脚本主机或其他脚本引擎中执行。
我知道 3 种方法,每种方法都有自己的缺点。
eval()
方法:function wrapper () { var str = ''; for (var i=0; i<arguments.lenght; i++) str += (str ?', ':'') + ',arguments['+i+']'; return eval('[native_function] ('+str+')'); }
switch()
方法:function wrapper () { switch (arguments.lenght) { case 0: return [native_function] (arguments[0]); break; case 1: return [native_function] (arguments[0], arguments[1]); break; ... case n: return [native_function] (arguments[0], arguments[1], ... arguments[n]); } }
apply()
方法:function wrapper () { return [native_function].apply([native_function_namespace], arguments); }
你问他们怎么了?
好吧,我们要深入研究为什么
eval()
是邪恶的所有原因吗?还有所有的字符串连接......不是一个被标记为“优雅”的解决方案。人们永远无法知道最大
n
以及需要准备多少case
。这也会将脚本过度拉伸(stretch),并违反神圣的 DRY 原则。脚本可以在不支持
<apply()
方法的旧版(JavaScript 1.3/ECMA-262-3 之前)引擎上执行。
现在是问题部分:还有其他解决方案吗?
最佳答案
只需使用apply()
。对于您的过时执行引擎,只需执行此操作
if ( 'undefined' == typeof Function.prototype.apply )
{
Function.prototype.apply = function( context, args )
{
// whatever hacky way you want to implement it - i guess eval.
}
}
关于javascript - 如何在 JavaScript 中创建可变参数(具有可变长度参数列表)函数包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2472702/