funky 需要是一个“高阶”函数,它将您的输入函数“转换”为只运行第一个 n 次的函数:
function funky(fn, n) {
return function() {
return n-- > 0 ? fn.apply(this, arguments) : "No more";
};
}
在这里,我们使用fn.apply 允许用户通过this 和返回函数的参数,因此您可以执行以下操作:
var hey = funky(function(name){ alert("hey " + name); }, 3);
hey("Bob"); // alert("hey Bob")
hey("Joe"); // alert("hey Joe")
hey("Sam"); // alert("hey Sam")
hey("Don"); // no alert, returns "No more"
将参数传递给派生函数已经足够有用了,但是在什么情况下它会尊重this?显然,只有在涉及对象及其方法的情况下。考虑:
// Constructor to create new MyAlerter object, with magic number
var MyAlerter = function(magic) {
this.magic = magic;
}
// Method on MyAlerter to put up alert with magic number
MyAlerter.prototype.alert = function(name) {
alert("hey " + name + ", your magic number is " + this.magic);
};
现在我们要基于alert 方法创建一个函数/方法hey,它将调用次数限制为三个。我们已经有了 funky 函数来做到这一点:
MyAlerter.prototype.hey = funky(MyAlerter.prototype.alert, 3);
现在我们可以这样做了:
var alerter = new MyAlerter(42);
alerter.hey("Bob"); // alert("hey Bob, your magic number is 42")
alerter.hey("Joe"); // alert("hey Joe, your magic number is 42")
alerter.hey("Sam"); // alert("hey Sam, your magic number is 42")
alerter.hey("Don"); // no alert, returns "No more"
通过通过this 调用hey 到底层函数alert,通过funky 内部的fn.apply 完成,alert 接收正确的this 并能够访问幻数。