Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES6中的 Set & Map #14

Open
39Er opened this issue May 24, 2017 · 0 comments
Open

ES6中的 Set & Map #14

39Er opened this issue May 24, 2017 · 0 comments

Comments

@39Er
Copy link
Owner

39Er commented May 24, 2017

Set

ES5中的set通常如此表示:

var set = Object.create(null);
set.foo = true;
// checking for existence
if (set.foo) {
	// code to execute
}

ES6:

let set = new Set();
set.add(5);
set.add("5");
console.log(set.size); // 2

ES6的Set去重内部使用的是Object.is()方法,所以5和'5'是两个不同的子元素。

Set方法包括:

  • add() 新增元素
  • delete() 删除元素
  • clear() 清空set
  • has() 校验是否存在元素
  • forEach() 遍历set

可以利用set的特性对数组进行去重:

function eliminateDuplicates(items) {
	return [...new Set(items)];
}
let numbers = [1, 2, 3, 3, 3, 4, 5],
noDuplicates = eliminateDuplicates(numbers);
console.log(noDuplicates); // [1,2,3,4,5]

Set存在的问题:

let set = new Set(),
key = {};
set.add(key);
console.log(set.size); // 1
// eliminate original reference
key = null;
console.log(set.size); // 1
// get the original reference back
key = [...set][0];

set中的对象元素置空后,仍然可以通过set获取到元素原来的引用,这样容易造成内存泄漏。
于是ES6引入了WeakSet。

WeakSet

let set = new WeakSet(),
key = {};
// add the object to the set
set.add(key);
console.log(set.has(key)); // true
// remove the last strong reference to key (also removes from weak set)
key = null;

当WeakSet中的对象元素置空后,WeakSet中的元素也被移除了。

注意: WeakSet中只能保存对象元素

WeakSet与Set的不同:

  • 在WeakSet中,add()、delete()、has()方法接收到非对象参数时会报错;
  • WeakSet不是可迭代的,所以不能使用for-of循环;
  • WeakSet不显示任何迭代器,没有keys()和values(),所以没有办法确定一个WeakSet的内容;
  • WeakSet没有forEach()方法;
  • WeakSet没有size属性

Map

ES5 中的 Map实现:

var map = Object.create(null);
map.foo = "bar";
// retrieving a value
var value = map.foo;
console.log(value); // "bar"

ES5中map实现的问题:

var map = Object.create(null);
map[5] = "foo";
console.log(map["5"]); // "foo"

var map = Object.create(null),
	key1 = {},
	key2 = {};
map[key1] = "foo";
console.log(map[key2]); // "foo"

在ES5中,会自动将数字key转换为string,所以map[5]和map['5']的值是一样的。

key1和key2的value值相同,因为key1和key2被转换为string,对象属性必须是string,因为[object Object]是对象的默认string值,所以key1和key2都转换为这个string值,所以他们的value相同。

ES6 Map:

let map = new Map();
map.set("title", "Understanding ECMAScript 6");
map.set("year", 2016);
console.log(map.get("title")); // "Understanding ECMAScript 6"
console.log(map.get("year")); // 2016

在ES6的Map中每一个对象都被看成是唯一的。

Map方法:

  • set() 增加、修改键值对
  • has(key) 校验是否存在键值
  • get(key) 获取key的value
  • delete(key) 删除键
  • clear() 清空map
  • forEach() 遍历map
  • keys() 返回键数组
  • values() 返回值数组

Map的key也存在和Set同样的内存泄漏隐患。

WeakMap

let map = new WeakMap(),
element = document.querySelector(".element");
map.set(element, "Original");
let value = map.get(element);
console.log(value); // "Original"
// remove the element
element.parentNode.removeChild(element);
element = null;
// the weak map is empty at this point

WeakMap的key只能为Object

WeakMap的方法:

  • delete(key);
  • get(key);
  • set(key);
  • has(key);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant