John Resig有一篇关于部分申请的热门博客文章:http://ejohn.org/blog/partial-functions-in-javascript/它在很多地方都有提及,并有
但是,博客文章中的代码不起作用。这是:
Function.prototype.partial = function(){
var fn = this, args = Array.prototype.slice.call(arguments);
return function(){
var arg = 0;
for ( var i = 0; i < args.length && arg < arguments.length; i++ )
if ( args[i] === undefined )
args[i] = arguments[arg++];
return fn.apply(this, args);
};
};
var delay = setTimeout.partial(undefined, 10);
delay(function(){
alert( "A call to this function will be temporarily delayed." );
});
现在,如果您尝试在控制台中运行它,它将正常工作。但是,如果您尝试再次使用延迟功能,它将无法正常工作。尝试在运行第一个段后在控制台中运行它:
delay(function(){
alert( "This is a test" );
});
请注意,第二条消息不会出现 - 第一条消息会出现。当然,如果你重新设置延迟功能,它可以工作,但是为什么你每次使用它时都想重新制作部分应用的功能呢?
现在,鉴于此博客文章是“部分应用程序javascript”的第二个Google结果,并且似乎相当受欢迎,我怀疑它完全被破坏了。另一方面,大量的代码示例和流行的Prototype.js库以我期望的方式运行 - 可重用的部分应用程序。他的currying功能,略高于页面,完全符合我的预期。因此:
答案 0 :(得分:6)
John Resig的代码不正确吗?
是。即使你怀疑它,它只是 完全坏了。
undefined
的部分申请不会多次工作,因为他修改了共享的args
数组。没有任何undefined
的部分申请根本不起作用。
它仍然可能有助于生成仅被调用一次的回调等,但它不是很有用。
修正:
Function.prototype.partial = function() {
var fn = this, args = arguments;
return function() {
var filledArgs = Array.prototype.slice.call(args);
for (var i=0, arg=0; arg < arguments.length; i++)
if (filledArgs[i] === undefined)
filledArgs[i] = arguments[arg++];
return fn.apply(this, filledArgs);
};
};
请注意,与将filledArgs
的长度限制为部分给定的参数(包括undefined
s)的数量不同,这现在确实接受了任意多个附加参数,并且只是以类似于{的方式附加它们。 {3}}
哦,虽然我们还在,但John Resig也得到了bind
这个词的错误,他正在用他的.curry
方法做currying(Wikipedia isn&# 39;这在2008年是准确的。)