对象的键是无序的,键的类型只能是数字或字符串或Symbol,只能通过其他方式遍历keys,for...in等 Map的键是有序的,键的类型可以是任意类型,可以直接和数组一样直接遍历.
Map是为了快速搜索和查找数据而生的 set,get,has,clear
Map与WeakMap 有时想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用。一旦不再需要这两个对象,就必须手动删除这个引用,否则垃圾回收机制就不会释放对象占用的内存。WeakMap的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用.
什么是缓存?
所谓函数缓存,就是将函数运算过的结果缓存起来,这种做法是典型的用内存去换取性能的手段,常用于缓存数据计算结果和缓存对象。缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快地得到处理
为什么需要?
在前端页面中,有些数据(比如数据字典中的数据),可以在第一次请求的时候全部拿过来保存在js对象中,以后需要的时候就不用每次都去请求服务器了。对于那些大量使用数据字典来填充下拉框的页面,这种方法可以极大地减少对服务器的访问。简单点说,就是提供便利,减少查询次数和所消耗的时间。
JavaScript 中的缓存的概念主要建立在两个概念之上, 闭包+高阶函数
利用高阶函数的思想来实现一个简单的缓存,在函数内部用一个对象存储输入的参数,如果下次再输入相同的参数,那就比较一下对象的属性,把值从这个对象里面取出来,不必再继续往运行,这样就极大的节省了客户端等待的时间
JS实现函数缓存
const cache = {} // 存储缓存数据的对象
return function(...args) { // 这里用到数组的扩展运算符
// 将参数作为cache的key
const _args = JSON.stringify(args)
// 如果已经缓存过,直接取值。否则重新计算并且缓存
return cache[_args] || (cache[_args] = fn.apply(fn, args))
}
}
const add = function(a, b) {
console.log('开始缓存')
return a + b
}
const adder = memorize(add)
console.log(adder(2, 6)) // 输出结果: 开始缓存 8 // cache: { '[2, 6]': 8 }
console.log(adder(2, 6)) // 输出结果: 8 //cache: { '[2, 6]': 8 }
console.log(adder(10, 10)) // 输出结果: 开始缓存 20 // cache: { '[2, 6]': 8, '[10, 10]': 20 }
只有第一次会输出‘开始缓存’, 之后只要参数想同,每次取值都会在缓存里取。这里需要注意一下cache不可以是Map数据结构,因为Map的键是使用===比较的,[1]!==[1],因此即使传入相同的对象或者数组,那么还是被存为不同的键