使用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

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 4,000评论 2 16
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 652评论 1 7
  • JS 函数 函数分为两类具名函数、匿名函数,其变型可以包括自执行函数、递归函数 具名函数含有名字的函数functi...
    小早online阅读 320评论 0 9
  • 介绍JavaScript的基本数据类型。 ECMAScript中有5中简单数据类型(也称为基本数据类型): Und...
    过往的雨阅读 190评论 0 1
  • 在欧洲,亚洲或者南美洲长大的人有着非常不同的守时观念。就像丹尼尔解释的“迟到五分钟虽然晚了但是在美国的商务会面中是...
    柳涛虹阅读 21评论 3 2