图中为整个代码的执行过程。从js层初始化一个集合到底层的实现,其他的增删改查也类似的流程。底层是一个由UHashElement结构体组成的数组,UHashElement结构体包括每个元素的键值和哈希值。UHashtable中还含有一些扩大和缩小哈希表的操作。
set和map基本类似,下面通过代码大概了解一下。
function WeakMapConstructor(iterable) {
// 必须加new
if (IS_UNDEFINED(new.target)) {
throw MakeTypeError(kConstructorNotFunction, "WeakMap");
}
// 初始化底层哈希表
%WeakCollectionInitialize(this);
// 如果没有传参则创建一个空的哈希表
if (!IS_NULL_OR_UNDEFINED(iterable)) {
// set函数在下面代码中挂载
var adder = this.set;
// 判断set是不是函数
if (!IS_CALLABLE(adder)) {
throw MakeTypeError(kPropertyNotFunction, adder, 'set', this);
}
// 迭代参数,逐个加到哈希表中
for (var nextItem of iterable) {
if (!IS_RECEIVER(nextItem)) {
throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
}
// 把内容加到哈希表
%_Call(adder, this, nextItem[0], nextItem[1]);
}
}
}
function WeakMapGet(key) {
if (!IS_WEAKMAP(this)) {
throw MakeTypeError(kIncompatibleMethodReceiver,
'WeakMap.prototype.get', this);
}
if (!IS_RECEIVER(key)) return UNDEFINED;
// 根据键拿到一个hashcode,然后到哈希表里进行操作
var hash = GetExistingHash(key);
if (IS_UNDEFINED(hash)) return UNDEFINED;
return %WeakCollectionGet(this, key, hash);
}
我们可以看到js层的代码很简单,我们new Map的时候创建一个哈希表,增删改查的时候,首先根据key拿到一个hashcode,然后到底层哈希表里进行操作。
时间有限,后面有时间继续研究,,,