once 源码解析

once 源码解析

正文

0. 基本信息

  • version:v1.0.4
  • 功能:返回只执行一次的函数的高阶函数

吐槽:作者把 wrappy 库的 sample 包一包就也能发个包,也是很偷懒

1. 源码解析

1.1 源码结构

  • once.js(阅读笔记:/once.js/0_structure.js
var wrappy = require('wrappy');
module.exports = wrappy(once);
module.exports.strict = wrappy(onceStrict);

once.proto = once(function () {});

function once(fn) {}

function onceStrict(fn) {}

整个库导出了两个方法,一个是基本款的 once;一个是严格版本onceStrict

1.2 once 基本款

  • once.js(阅读笔记:/once.js/1_once.js
// called 标志是否调用过
// value 记录结果值
function once(fn) {
  var f = function () {
    if (f.called) return f.value;
    f.called = true;
    return (f.value = fn.apply(this, arguments));
  };
  f.called = false;
  return f;
}

基本款的基本就是用一个 f.called 属性来记录是否调用过了

注:这里其实可以加一句 fn = null,来释放对 fn 函数的指针,使 Node 编译器正确回收函数对象

1.3 onceStrict 严格模式

  • once.js(阅读笔记:/once.js/2_onceStrict.js
// called 标志是否调用过
// onceError 为报错信息
function onceStrict(fn) {
  var f = function () {
    if (f.called) throw new Error(f.onceError);
    f.called = true;
    // 啊这里还要 value 干嘛啦,偷懒诶
    return (f.value = fn.apply(this, arguments));
  };
  var name = fn.name || 'Function wrapped with `once`';
  f.onceError = name + " shouldn't be called more than once";
  f.called = false;
  return f;
}

严格模式就是多次调用的时候多一个报错罢了

1.4 原型方法

  • once.js(阅读笔记:/once.js/3_proto.js
once.proto = once(function () {
  Object.defineProperty(Function.prototype, 'once', {
    value: function () {
      return once(this);
    },
    configurable: true,
  });

  Object.defineProperty(Function.prototype, 'onceStrict', {
    value: function () {
      return onceStrict(this);
    },
    configurable: true,
  });
});

这个 proto 方法有点不知道作者想干嘛,实用价值说实在偏低,而且还会污染全局的 Function.prototype 方法

其他资源

参考连接

TitleLink
once - npmhttps://www.npmjs.com/package/once
isaacs/oncehttps://github.com/isaacs/once

阅读笔记参考

https://github.com/superfreeeee/Blog-code/tree/main/source_code_research/once-1.4.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值