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

Creating a function that can be invoked a given number of times and no more

假设您有一个功能,您可以使用 "hey" 输入警报,并且您希望允许这种情况发生给定的次数——比如 2 次或 3 次,或者任何你想要的——然后给定的数字提醒负数或 "no more" 类型字符串的次数相同。

因此您希望您的函数调用 n 次

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

hey();

你是怎么做到的?

你是说像 for 循环?

function funky (fn, n) {
    for (var i = 0; i < n; i += 1) {
        fn();
    }
}

funky(function () {
    alert('ABC');
}, 3);

如果您不希望它立即 运行 那么您可以这样做:

function funky(fn, n) {
    this.run = function() {
        for (var i = 0; i < n; i += 1) {
            fn();
        }
    }
}

var hey = new funky(function() {
    alert('ABC');
}, 3);

hey.run();//Alerts ABC 3 times

Fiddle

另外:

function funky(fn, n) {
    return function() {
        for (var i = 0; i < n; i += 1) {
            fn();
        }
    }
}

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

hey();//Alerts ABC 3 times

funky 需要是一个 "higher-order" 函数,它 "transforms" 将您的输入函数转换为仅运行前 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方法的基础上做一个function/methodhey,限制调用次数为3次。我们已经有了 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"

通过调用 heythis 传递给基础函数 alert,由 funky 中的 fn.apply 完成,alert 收到正确的 this 并能够访问幻数。