第6章 集合引用类型
问题:
- 
为什么称作集合引用类型?集合引用类型是相对基本引用类型来讲的,集合的出现就是为了更方便地操作多个对象。因此,集合是存储对象最常用的一种方式。集合对基本数据类型“不感兴趣”,但是因为基本数据类型有了其相应封装的对象,有自动拆箱和封箱的功能,在基本数据类型与其对象之间转换很方便,因此集合引用类型传入基本数据,在调用方法时会在后台将其封装成对象再进行操作。 集合引用类型包括Array、TypedArray、Map、WeakMap、Set、WeakSet。 
- 
为什么会有这么多集合引用类型?- 
Array:有时需要将不同类型的数据按顺序保存,这时可以使用Array,类似Python中的 list。主要功能包括空位占位、迭代方法、复制填充、多方法创建、类型转换、栈方法、队列方法、排序方法、打平切片删除插入替换方法、搜索方法、归并方法。 
- 
TypedArray:JavaScript有时需要操作某一特定数值类型的数据(如 int16),而且也只需要这种类型数据,因为这样可以提升向原生库传输数据的效率,但是Array里保存着各种类型的数据,而且数值类型的保存的字节序和系统原生的字节序可能不一样,极大地降低了传输效率,因此出现了定型数组,它是一种ElementType且遵循系统原生字节序的ArrayBuffer视图,可以提高与WebGL等原生库交换二进制数据的效率。 
- 
Map:在ES 6 之前,在JavaScript中实现“键-值”式方式存储可以用Object方式来高效地完成,但是这种方式存在很多问题,如在频繁添加和删除键值对的场景下会严重影响性能,因此出现了Map。 ![]() 
- 
WeakMap:弱映射,其中的“弱”描述的是JavaScript垃圾回收程序对待“弱映射”中键的方式。 在 JavaScript 里,map API 可以通过使其四个 API 方法共用两个数组(一个存放键,一个存放值)来实现。给这种 map 设置值时会同时将键和值添加到这两个数组的末尾。从而使得键和值的索引在两个数组中相对应。当从该 map 取值的时候,需要遍历所有的键,然后使用索引从存储值的数组中检索出相应的值。 但这样的实现会有两个很大的缺点,首先赋值和搜索操作都是 O(n) 的时间复杂度( n 是键值对的个数),因为这两个操作都需要遍历全部整个数组来进行匹配。另外一个缺点是可能会导致内存泄漏,因为数组会一直引用着每个键和值。这种引用使得垃圾回收算法不能回收处理他们,即使没有其他任何引用存在了。 相比之下,原生的 WeakMap 持有的是每个键对象的“弱引用”,这意味着在没有其他引用存在时垃圾回收能正确进行。原生 WeakMap 的结构是特殊且有效的,其用于映射的 key 只有在其没有被回收时才是有效的。 正由于这样的弱引用,WeakMap 的 key 是不可枚举的 (没有方法能给出所有的 key)。如果key 是可枚举的话,其列表将会受垃圾回收机制的影响,从而得到不确定的结果。因此,如果你想要这种类型对象的 key 值的列表,你应该使用 Map。 基本上,如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。 
- 
Set:Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。另外,NaN和undefined都可以被存储在Set 中, NaN之间被视为相同的值(NaN被认为是相同的,尽管 NaN !== NaN)。 
- 
WeakSet:WeakSet 对象是一些对象值的集合, 并且其中的每个对象值都只能出现一次。在WeakSet的集合中是唯一的。 - 与Set相比,WeakSet只能是对象的集合,而不能是任何类型的任意值。
- WeakSet持弱引用:集合中对象的引用为弱引用。 如果没有其他的对- WeakSet中对象的引用,那么这些对象会被当成垃圾回收掉。 这也意味着WeakSet中没有存储当前对象的列表。 正因为这样,- WeakSet是不可枚举的。
 
- 与
 
- 
- 
各集合引用类型在适合在什么时候使用?
 
                     
                    
                 
                    
                

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号