lodash源码分析之缓存使用方式的进一步封装

在世界上所有的民族之中,支配着他们的喜怒选择的并不是天性,而是他们的观点。

——卢梭《社会与契约论》

本文为读 lodash 源码的第九篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

gitbook也会同步仓库的更新,gitbook地址:pocket-lodash

前言

在之前的《lodash源码分析之Hash缓存》和《lodash源码分析之List缓存》介绍过 lodash 的两种缓存方式,在《lodash源码分析之缓存方式的选择》中介绍过这两种缓存方式和 Map 的封装,lodash 会根据缓存类型来选择最优的缓存方式。

但是在 MapCache 类中,要初始化缓存和设置缓存都需要提供 keyvalue 组成的二维数组,因此在 SetCache 类中,lodash 提供了一种更方便的缓存设置方式,只需要提供缓存的值即可。

依赖

import MapCache from ‘./MapCache.js‘

lodash源码分析之缓存方式的选择

源码分析

const HASH_UNDEFINED = ‘__lodash_hash_undefined__‘

class SetCache {

  constructor(values) {
    let index = -1
    const length = values == null ? 0 : values.length

    this.__data__ = new MapCache
    while (++index < length) {
      this.add(values[index])
    }
  }

  add(value) {
    this.__data__.set(value, HASH_UNDEFINED)
    return this
  }

  has(value) {
    return this.__data__.has(value)
  }
}

SetCache.prototype.push = SetCache.prototype.add

总体思路

从源码中可以看到,SetCache 其实调用的是 MapCache 类,使用缓存的值作为 key ,所有的 key 对应的值都是 lodash 定义的标准 undefinedHASH_UNDEFINED ,正如之前文章中论述过的,这个值用于 Hash 缓存时,避免判断是缓存是否存在时出错。

判断缓存是否存在,只需要判断 MapCache 是否存在对应的 key

constructor

constructor(values) {
  let index = -1
  const length = values == null ? 0 : values.length

  this.__data__ = new MapCache
  while (++index < length) {
    this.add(values[index])
  }
}

这里构造函数不需要再传入 key-value 的二维数组了,只需要传入包含所有缓存值的数组即可。

__data__ 属性保存的其实是 MapCache 的实例。

初始化时只需要遍历需要缓存的数组 values ,然后调用 add 方法,设置缓存即可。

add

add(value) {
  this.__data__.set(value, HASH_UNDEFINED)
  return this
}

add 方法用来设置缓存。

其实调用的是 MapCahce 实例的 set 方法,使用缓存值 value 作为 key ,用 HASH_UNDEFINED 作为缓存值。

### has

has(value) {
  return this.__data__.has(value)
}

has 方法用于判断缓存是否存在。

只需要调用 MapCache 实例的 has 方法即可。

push

SetCache.prototype.push = SetCache.prototype.add

push 方法只是 add 方法的别名。

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:

作者:对角另一面

原文地址:https://www.cnblogs.com/hefty/p/8375813.html

时间: 2024-10-12 09:07:26

lodash源码分析之缓存使用方式的进一步封装的相关文章

jQuery1.9.1源码分析--数据缓存Data模块

阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(elem, name, data)源码分析 internalRemoveData方法源码分析 internalData方法的源码分析 jQuery.fn.extend({data: function( key, value ) {}})源码分析 jQuery.extend({removeData: function( elem, name ) {}})源码分

cglib源码分析1 ----- 缓存和KEY

cglib是一个java 字节码的生成工具,它是对asm的进一步封装,提供了一系列class generator.研究cglib主要是因为它也提供了动态代理功能,这点和jdk的动态代理类似. 一. Cache的创建 与jdk动态代理一样,cglib也提供了缓存来提高系统的性能,对于已经生成的类,直接使用而不必重复生成.这里不得不提到一个比较重要的抽象类AbstractClassGenerator,它采用了模版方法的设计模式,protected Object create(Object key)

【转】MaBatis学习---源码分析MyBatis缓存原理

[原文]https://www.toutiao.com/i6594029178964673027/ 源码分析MyBatis缓存原理 1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然也在内部提供了相应的支持.通过在框架层面增加缓存功能,可减轻数据库的压力,同时又可以提升查询速度,可谓一举两得.MyBatis 缓存结构由一级缓存和二级缓存构成,这两级

lodash源码分析之Hash缓存

在那小小的梦的暖阁,我为你收藏起整个季节的烟雨. --洛夫<灵河> 本文为读 lodash 源码的第四篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 作用与用法 Hash 顾名思义,就是要有一个离散的序列,根据 key 来储取数据.而在 javascript 中,最适合的无疑是对象了. Hash 在 lodash 的 .internal 文件夹中,作为内部文件来使用.lodash 会根

lodash源码分析之compact中的遍历

小时候, 乡愁是一枚小小的邮票, 我在这头, 母亲在那头. 长大后,乡愁是一张窄窄的船票, 我在这头, 新娘在那头. 后来啊, 乡愁是一方矮矮的坟墓, 我在外头, 母亲在里头. 而现在, 乡愁是一湾浅浅的海峡, 我在这头, 大陆在那头. --余光中<乡愁> 本文为读 lodash 源码的第三篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 作用与用法 compact 函数用来去除数组中的

lodash源码分析之去重--uniq方法

lodash.js包是node开发中常用的js工具包,里面有许多实用的方法,今天分析常用的一个去重方法---uniq 用法 _.uniq([2, 1, 2]) // => [2, 1] 源码包 // uniq.js import baseUniq from './.internal/baseUniq.js' function uniq(array) { return (array != null && array.length) ? baseUniq(array) : [] } ex

jQuery 2.0.3 源码分析 数据缓存

转载http://www.cnblogs.com/aaronjs/p/3370176.html 历史背景: jQuery从1.2.3版本引入数据缓存系统,主要的原因就是早期的事件系统 Dean Edwards 的 ddEvent.js代码 带来的问题: 没有一个系统的缓存机制,它把事件的回调都放到EventTarget之上,这会引发循环引用 如果EventTarget是window对象,又会引发全局污染 不同模块之间用不同缓存变量 一般jQuery开发,我们都喜欢便捷式的把很多属性,比如状态标志

Mybatis源码分析自定义缓存、分页的实现

一.缓存 我们知道,在Mybatis中是有缓存实现的.分一级缓存和二级缓存,不过一级缓存其实没啥用.因为我们知道它是基于sqlSession的,而sqlSession在每一次的方法执行时都会被新创建.二级缓存是基于namespace,离开了它也是不行.有没有一种方式来提供自定义的缓存机制呢? 1.Executor Executor是Mybatis中的执行器.所有的查询就是调用它的<E> List<E> query()方法.我们就可以在这里进行拦截,不让它执行后面的查询动作, 直接从

Spark源码分析:多种部署方式之间的区别与联系(1)

从官方的文档我们可以知道,Spark的部署方式有很多种:local.Standalone.Mesos.YARN.....不同部署方式的后台处理进程是不一样的,但是如果我们从代码的角度来看,其实流程都差不多. 从代码中,我们可以得知其实Spark的部署方式其实比官方文档中介绍的还要多,这里我来列举一下: 1.local:这种方式是在本地启动一个线程来运行作业: 2.local[N]:也是本地模式,但是启动了N个线程: 3.local[*]:还是本地模式,但是用了系统中所有的核: 4.local[N