创建一个可以调用给定次数而不再调用的函数

0 javascript function higher-order-functions

假设你有一个功能,你可以用"嘿"输入一个警报,你想允许它发生给定次数 - 比如2,或3,或任何你想要的 - 然后在给定的数字后提醒相同的数量时间为负数或"不再"类型的字符串.

所以你希望你的函数调用n次

var hey = funky(function(){alert("hey")},3);

hey();
Run Code Online (Sandbox Code Playgroud)

你是怎样做的?

小智 5

funky需要是一个"高阶"函数,它将你的输入函数"转换"为只运行第一次的函数n:

 function funky(fn, n) {
     return function() {
         return n-- > 0 ? fn.apply(this, arguments) : "No more";
     };
 }
Run Code Online (Sandbox Code Playgroud)

在这里,我们习惯于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"
Run Code Online (Sandbox Code Playgroud)

将参数传递给派生函数是有用的,但在什么情况下它会尊重它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);
};
Run Code Online (Sandbox Code Playgroud)

现在我们想要hey基于该alert方法创建一个函数/方法,该方法将调用次数限制为三次.我们已经有了funky这样做的功能:

MyAlerter.prototype.hey = funky(MyAlerter.prototype.alert, 3);
Run Code Online (Sandbox Code Playgroud)

现在我们可以这样做:

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"
Run Code Online (Sandbox Code Playgroud)

通过调用底层函数的thiswith,由内部完成,接收正确的并且能够访问幻数.heyalertfn.applyfunkyalertthis