如何捕获函数中所需的参数数(套用函数部分应用程序)
how capture the arguments number need in a function (currying function partial application)
我正在研究循环函数和部分应用程序,我正在尝试改进schonfinkelize函数:
function schonfinkelize(fn){
var
slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function(){
var
new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
}
}
这个函数允许传递作为参数,函数和作为参数传递的函数的一部分参数(部分应用程序),所以第一次返回一个函数,然后当你再次触发函数的结果。
function add(x, y, z){
return x + y + z;
}
var val = schonfinkelize(add, 1, 2);
console.log( val(3) ) // console output--> 6
我想在schonfinkelize内部检查函数"add"所需的参数数量(但它应该与每个函数一起工作),所以我可以选择何时返回另一个函数或直接返回函数"add"的结果。
因为如果我这样使用schonfinkelize
var val2 = schonfinkelize(add, 1, 2, 3);
console.log( val2 ) // --> function
console.log( val2() ) // --> 6
我必须两次触发函数,而不是想避免这种行为,如果参数足够,直接定义值
一个可能的解决方案如下:
function schonfinkelize(fn){
var
slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
//* I have added this ********
if(fn.apply(null, stored_args))
return fn.apply(null, stored_args);
//****************************
return function(){
var
new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
}
}
可能是因为它立即返回fn的结果。apply(null, stored_args)返回的东西不是"null"或"NaN",但我认为不是真正的性能,然后我想工作与参数
只要您要求为传递的函数定义的参数反映最终要接收的参数的实际数量,您就可以使用函数的.length
属性将传递的参数与预期的参数进行比较。
function schonfinkelize(fn) {
if (fn.length === arguments.length - 1)
return fn.apply(this, [].slice.call(arguments, 1));
var
slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function(){
var
new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
}
}
边注…如果您将fn
缓存到一个新变量中,并使用this
值覆盖第一个参数,则可以避免.slice()
,然后使用.call.apply()
…
if (fn.length === arguments.length - 1) {
var func = fn;
arguments[0] = this;
return func.call.apply(func, arguments);
}
在严格模式浏览器中,您甚至可以避免使用make the new variable,因为参数不再映射到arguments
中的更改。但这在不支持严格模式的浏览器中不起作用
我不认为有一个正确的方法来确定任意函数的参数数量。如果有必要,我更喜欢将len
存储在函数中,并检查它是否被定义,如果是,如果fn.len == stored_args.length
则返回函数,仅返回值。
function schonfinkelize(fn){
var
slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
if (fn.len != undefined && fn.len == stored_args.length) {
var val = fn.apply(null, stored_args);
return function () {
return val;
};
}
return function () {
var
new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
};
}
var f = function (a, b, c) {
return a + b + c;
};
f.len = 3;
var g = schonfinkelize(f, 1, 2);
alert(g); // function () { var new_args = slice.call(arguments), args = stored_args.concat(new_args); return fn.apply(null, args); };
alert(g(3)); // 6
var g = schonfinkelize(f, 1, 2, 3);
alert(g); // function () { return val; };
alert(g()); // 6
我还想提出一个个人的代码演变,但我不得不说感谢斜眼已经解决了这个问题,只是建议我使用属性.length。在我看来,下一个层次是允许创建一个局部函数,每次都可以调用它,直到完成填充所有参数,我也简化了代码:
function schonfinkelize(fn, stored_args){
if(fn.length == stored_args.length)
return fn.apply(null, stored_args);
return function(){
var
new_args = arguments[0],
args = stored_args.concat(new_args);
if(fn.length == args.length)
return fn.apply(null, args);
return schonfinkelize(fn, args);
}
}
function add(x, y, w, z){
return x + y + w + z;
}
var
val = schonfinkelize(add, [1, 2, 3, 4]),
val2 = schonfinkelize(add, [1, 2]),
val3 = schonfinkelize(add, [1]);
// checking
console.log(val); // output --> 10 // called only 1 time
console.log(val2([3, 4])); // output --> 10 // called in 2 times
val3 = val3([2]);
val3 = val3([3]);
console.log(val3([4])); // output --> 10 // called 4 times!
- 如何远程检查JavaScript应用程序的函数调用堆栈
- 如何将某个“;函数“;在Node.js的网络应用程序中
- 当调用JS函数具有alert()时,应用程序将被冻结
- 如何根据JavaScript函数的结果用PHP编写数据库?(FB应用程序)
- 为什么谷歌应用程序的电子表格setValue函数没有在单元格中设置值
- 谷歌应用程序脚本-正在尝试使用getUrl.TypeError:在对象工作表中找不到函数getUrl
- 使用Google应用程序脚本将数组传递给客户端函数
- 在加载移动应用程序页面时调用Javascript函数
- 是否可以将我网站上的普通javascript和css函数包含到我的angularjs应用程序中
- 谷歌应用程序脚本:;范围不是函数,它是对象;尝试在单元格中放置注释时出错
- 谷歌应用程序脚本:如何在没有用户交互的情况下调用绑定到处理程序的函数
- 在固定间隔内调用 AJAX 函数是否会减慢应用程序的速度
- JavaScript 函数 mOver(obj) 应用程序
- 如何使用 Office 365 加载项(以前称为 Office 相关应用程序)将功能区和用户可定义的函数添加到 Exce
- Javascript setTimeOut 函数与 .net 中 Windows 应用程序的计时器不匹配
- $q服务 - 我应该在新的 AngularJS 应用程序中使用 CommonJS 风格还是构造函数风格
- 为什么我们将 Angular 应用程序包装在一个函数中
- AngularJS控制器中的函数只调用了两次[Phonegap应用程序]
- 适用于 Javascript 函数的应用程序范围的身份验证处理程序
- 如何捕获函数中所需的参数数(套用函数部分应用程序)