FIFO (First Input First Output),先入先出队列(Queue),数据结构的一种。它的特征是按序执行指令,先进入队列的指令先完成并出队列,跟着才执行队列第二个指令。
现在如果要用 JavaScript 实现一个 FIFO
缓存方法,有下面几点要注意:
- 队列要有上限
limit
,即队列的最大容量,它判断超出容量后让最早进入的元素移出队列。 - 它有一个新增元素的方法
set
,即将一个新的指令加入到队列的方法。 - 它要能根据索引获取某个元素具体值的方法
get
我们使用面向对象编程范式
编写 FifoCache
构造函数:
// 构造函数 FifoCache
function FifoCache(limit){
this.limit = limit || 10
this.map = {}
this.keys = []
}
- 构造函数
FifoCache
接收一个参数limit
作为实例队列的上限。 - 给它定义内部变量
map
,它是一个对象,以key-value
形式存储新增的元素。 - 给它定义内部变量
keys
,它是数组类型,保存了元素的key
的集合
添加新增元素的 set
方法
挂载到构造函数 FifoCache
原型对象上
FifoCache.prototype.set = function(key,value){
// 判断新增元素的key是否已经存在
if (!Object.prototype.hasOwnProperty.call(this.map,key)) {
// 判断是否已经到上限
if (this.keys.length === this.limit) {
// shift方法删除第一个元素
delete this.map[this.keys.shift()];
}
// 在keys数组加入新增的键名
this.keys.push(key);
}
// 给map对象新增元素对应的key-value
this.map[key] = value;
}
Object.prototype.hasOwnProperty.call
语句判断新增到元素是否存在相同的key
,为什么要这么调用,因为 JavaScript 没有将hasOwnProperty
作为一个敏感词,即我们可以自定义一个属性名为hasOwnProperty
,如此通过实例调用就找不到原型链的同名方法。- 如果
keys
数组长度超过了上限limit
,要删除掉map
对象中对应数组keys
的第一个对象。 - 在
keys
数组中添加新增的key
,在map
对象中新增元素。
添加 get
方法
同样将这个方法定义在构造函数 FifoCache
原型对象上
FifoCache.prototype.get = function(key){
return this.map[key]
}
- 通过传入
key
从FIFO
缓存中获取对应的value
创建实例:
let myFifo = new FifoCache(2);
myFifo.set('key1',{id:1,title:'title1'});
myFifo.set('key2',{id:2,title:'title2'});
myFifo.set('key3',{id:3,title:'title3'});
console.log(myFifo.get('key3')); // {id: 3, title: "title3"}
- 创建一个上限为
2
的实例。 - 新增
3
个元素,第一个当然被挤掉了。
console.log(JSON.stringify(myFifo));
可以直接打印实例看看现在里面都有什么。
{
"limit":2,
"map":{
"key2":{
"id":2,
"title":"title2"
},
"key3":{
"id":3,
"title":"title3"
}
},
"keys":[
"key2",
"key3"
]
}
key
为 ‘key1’ 的元素被删掉了。
完整代码如下:
function FifoCache(limit){
this.limit = limit || 10
this.map = {}
this.keys = []
}
FifoCache.prototype.set = function(key,value){
if (!Object.prototype.hasOwnProperty.call(this.map,key)) {
if (this.keys.length === this.limit) {
delete this.map[this.keys.shift()];
}
this.keys.push(key);
}
this.map[key] = value;
}
FifoCache.prototype.get = function(key){
return this.map[key]
}
let myFifo = new FifoCache(2);
myFifo.set('key1',{id:1,title:'title1'});
myFifo.set('key2',{id:2,title:'title2'});
myFifo.set('key3',{id:3,title:'title3'});
console.log(myFifo.get('key3'));
以上便是用 JavaScript 模拟 FIFO
缓存。