在JavaScript中实现"一次"功能

Chr*_*kai 5 javascript closures

我有来自Jasmine.js的这个测试once函数的规范.我不知道如何实现这样的功能.

/* Functions that decorate other functions.  These functions return a version of the function
   with some changed behavior. */

// Given a function, return a new function will only run once, no matter how many times it's called
describe("once", function() {
  it("should only increment num one time", function() {
    var num = 0;
    var increment = once(function() {
      num++;
    });
    increment();
    increment();

    expect(num).toEqual(1);
  });
});
Run Code Online (Sandbox Code Playgroud)

我不太明白我该怎么做.我知道我应该做一次函数(myFunction){}但除此之外,我被困住了.我发现这与封闭有关,仍然无法绕过它.

小智 7

如果你不想使用 UnderscoreJS,你可以自己实现一个更简单的“once”函数,如下所示:

var once = function (func) {
  var result;

  return function () {
    if (func) {
      result = func.apply(this, arguments);
      func = null;
    }

    return result;
  }
};
Run Code Online (Sandbox Code Playgroud)

当您将函数作为参数传递给此一次函数时(作为参数作为“func”),它返回一个只能调用一次的函数。

简而言之,它通过创建一个结果变量并将使用其提供的参数调用函数的结果分配给该变量来实现这一壮举——但仅限于第一次运行。否则,当函数随后被调用时,它永远不会进入你的 if 语句(因为 func 变量在第一次调用中被设置为 null)和结果变量引用的值(在第一次调用期间设置并通过闭包访问)将被退回。


Rob*_*evy 5

从UnderscoreJS来源复制:

  _.once = function(func) {
    var ran = false, memo;
    return function() {
      if (ran) return memo;
      ran = true;
      memo = func.apply(this, arguments);
      func = null;
      return memo;
    };
  };
Run Code Online (Sandbox Code Playgroud)

http://underscorejs.org/docs/underscore.html