一。コレクションの役割と特徴
コレクションには Set/WeakSet、Map/WeakMap が含まれ、hash table に似ています。特徴は以下の通りです:
-
オブジェクトを hash table として使用する際の欠点を回避(プロトタイププロパティを回避するために、
Object.create(null)を使用してプロトタイプがnullの空のオブジェクトを作成する必要があるかもしれません。リテラル{}ではなく、{}=== Object.create(Object.prototype) のため) -
ユーザーデータとビルトインメソッドの競合を解消し、データをプロパティとして公開せず、
.keyまたは[key]でデータにアクセスできず、コレクションはプロトタイプチェーンからkeyを継承しません -
コレクションの走査順序は挿入順序と同じです(そして
for...ofなどのイテレーター関連の新機能を利用できます)。hash table の理論的な走査順序は不確定です(hash 関数に依存) -
has()メソッドをサポートし、包含性検出に使用され、indexOf よりも高速です
二.Set
unique 値のセット。構文は以下の通り:
// 作成、パラメータ iterable はオプション
new Set(iterable)
// 追加、value は任意のタイプ可能
Set.prototype.add(value)
// 削除 | クリア
Set.prototype.delete(value)|Set.prototype.clear()
// 検索
Set.prototype.has(value)
// 走査、callback(value, value, set)
Set.prototype.forEach(callbackFn[, thisArg])
// 要素数を取得
Set.prototype.size
// 各種イテレーターを取得、Map との互換性のため、Set 中では keys === values
set.keys()、set.values() と set.entries()
特徴:
-
自動重複除去、重複値は add できませんが、2 つのプロパティが同じオブジェクトは重複しないと見なされます
-
1 行のコードで配列の重複除去が完了:
Array.from(new Set(arr)) -
ユーザーデータとビルトインメソッドの競合を回避し、データをプロパティとして公開せず、
.keyまたは[key]でデータにアクセスできず、コレクションはプロトタイプチェーンからkeyを継承しません
例:
var set = new Set('12231');
// 自動重複除去
console.log(set); // Set {"1", "2", "3"}
// 重複値は add できません
set.add('1');
console.log(set); // Set {"1", "2", "3"}
set.add(1);
console.log(set); // Set {"1", "2", "3", 1}
set.add({a: 1});
// 重複しない
set.add({a: 1});
console.log(set); // Set {"1", "2", "3", 1, Object {a: 1}, Object {a: 1}}
2 つのプロパティ値が完全に同じオブジェクトは重複しないと見なされます(もちろん、2 つの同じオブジェクトを指す参照は重複します)。Set 内部の hash 関数は書き換えをサポートしません(セキュリティの考慮)、この動作を変更できません
三.Map
キーと値のペアのセット。構文は以下の通り:
// 作成、パラメータ pairs はオプション、pairs は[[key, val], ] 二次元配列、既存の Map など可能
new Map(pairs)
// 追加 | 変更/削除/クリア/検索/読み取り
map.set(key, val)/map.delete(key)|map.clear()/map.has(key)/map.get(key)
// 走査、callback(value, key, set)、パラメータ順序に注意
map.forEach(callback)
// 要素数を取得
Map.prototype.size
// 各種イテレーターを取得、キー/値/キーと値のペアを走査
map.keys()、map.values() と map.entries()
特徴:key は任意のタイプ可能、Object を含みます(オブジェクトのkey は String または Symbol のみとは異なります)
例:
var map = new Map([['a', 1], ['b', 2]]);
//!!! パラメータ順序に注意
map.forEach((val, key, arr) => {
console.log(`val = ${val}, key = ${key}`);
});
// log print:
// val = 1, key = a
// val = 2, key = b
// val = objA, key = [object Object]
注意:map.forEach のパラメータ順序は callback(value, key, set) で、Array.forEach と同様の callback(key, value, set) ではありません
四.WeakSet/WeakMap
機能が制限された弱参照コレクション。Set/Map の強参照によるメモリリーク問題を回避します。例えばset.add(domNode) の後domNode がremove されても、gc はdomNode オブジェクトを回収できません。set が強参照のため、set.delete(domNode) を呼び出した後でのみメモリを回収できます
特徴:
-
WeakSet は new, add, delete, has のみをサポート
-
WeakMap は new, get, set, delete, has のみをサポート
-
WeakSet の値と WeakMap のキーは必須で Object でなければなりません
-
イテレーションをサポートしません
-
gc は使用中の Weak コレクション内の無効な要素を回収できます
P.S.第 3 条は少し奇妙です(おそらく gc の考慮によるものです)
总之、メモリリークの可能性があるシナリオ(例えば頻繁な DOM 操作、複雑なアニメーションなど)では、弱コレクションの採用を検討してください
五。まとめ
1 行のコードで配列の重複除去が完了するのは、多少なりとも人を興奮させます
データ構造を手で作る日は徐々に過去になりつつあり、底层建築は完善されつつあります
###参考資料
- 《ES6 in Depth》:InfoQ 中文站が提供する無料電子書籍
コメントはまだありません