使用JS闭包来实现once函数

直接上代码

let _={
  once:function (f) {
    //计数器,采用闭包来保护私有变量
    let count=0;
    //保存闭包执行结果
    let result;
    return function () {
      count++;
      //once执行逻辑
      if(count===1){
        //采用apply执行函数
        result=f.apply({},arguments);
      }
      //返回函数执行结果
      return result;
    }
  }
};

let f=function (name) {
  console.log(name);
};

let t=_.once(f);

t('frank');
t('brenda');

#result
frank

上面的代码有一个缺陷,就是忽略了this的处理,在apply的时候直接指定了空对象,考虑如下调用

let f=function () {
  console.log(this.name);
};

let o={
  name:'frank',
  f:f
};

let t=_.once(o.f);

t();
t();

console输出undefined,显然不符合预期,重新改造后的代码如下

let _={
  once:function (f,_this) {
    let count=0;
    let result;
    return function () {
      count++;
      if(count===1){
        if(typeof _this==='undefined'){
          _this={};
        }
        result=f.apply(_this,arguments);
      }
      return result;
    }
  }
};

let f=function () {
  console.log(this.name);
};

let o={
  name:'frank',
  f:f
};

let t=_.once(o.f,o);

t();
t();

#result 
frank

推荐阅读更多精彩内容