length函数的属性告诉'expected'参数列表有多长:
console.log((function () {}).length); /* 0 */
console.log((function (a) {}).length); /* 1 */
console.log((function (a, b) {}).length); /* 2 etc. */
Run Code Online (Sandbox Code Playgroud)
但是,它是一个只读方法:
f = function (a) {};
alert(f.length); // 1
f.length = 3;
alert(f.length); // 1
Run Code Online (Sandbox Code Playgroud)
有没有办法以编程方式设置该长度?到目前为止我最接近的是使用Function构造函数:
f = new Function("a,b,c", "/* function body here */");
f.length; // 3
Run Code Online (Sandbox Code Playgroud)
但是,使用Function基本上是相同的eval,我们都知道它有多糟糕.我还有其他选择吗?
事实证明length函数的属性是可配置的,这意味着您可以使用.defineProperty更改函数的长度值.例:
function hi() {}
hi.length === 0; // Expected
Object.defineProperty(hi, "length", { value: 5 })
hi.length === 5; // Intriguing
Run Code Online (Sandbox Code Playgroud)
这适用于最新版本的Chrome和Firefox,但它在Safari(v9.1.1)中不起作用.
现在,这是我能想到的最好的解决方案.
makeFunc = function (length, fn) {
switch (length) {
case 0 : return function () { return fn.apply(this, arguments); };
case 1 : return function (a) { return fn.apply(this, arguments); };
case 2 : return function (a,b) { return fn.apply(this, arguments); };
case 3 : return function (a,b,c) { return fn.apply(this, arguments); };
case 4 : return function (a,b,c,d) { return fn.apply(this, arguments); };
case 5 : return function (a,b,c,d,e) { return fn.apply(this, arguments); };
case 6 : return function (a,b,c,d,e,f) { return fn.apply(this, arguments); };
case 7 : return function (a,b,c,d,e,f,g) { return fn.apply(this, arguments); };
case 8 : return function (a,b,c,d,e,f,g,h) { return fn.apply(this, arguments); };
case 9 : return function (a,b,c,d,e,f,g,h,i) { return fn.apply(this, arguments); };
default : return function (a,b,c,d,e,f,g,h,i,j) { return fn.apply(this, arguments); };
}
};
Run Code Online (Sandbox Code Playgroud)
用法示例:
var realFn = function () {
return "blah";
};
lengthSix = makeFunc(6, realFn);
lengthSix.length; // 6
lengthSix(); // "blah"
Run Code Online (Sandbox Code Playgroud)
就个人而言,每当我在编程时使用复制和粘贴时,我总是畏缩,所以我很高兴听到任何更好的选择.
更新
我想到了一种可以适用于任意大小的方法,与上面的例子不同,后者受到你想要复制和粘贴多少次的限制.本质上,它动态创建一个函数(使用new Function),它将返回一个正确大小的函数,然后只是代理通过你传递给它的任何函数.是的,这确实伤到了你的头脑.无论如何,我以为我会根据上述情况对它进行基准测试......
http://jsperf.com/functions-with-custom-length(你也可以看到'邪恶'代码).
邪恶的方法比hacky copypasta方法慢几百倍,所以你去.
| 归档时间: |
|
| 查看次数: |
1650 次 |
| 最近记录: |