title: es6基础知识6(set和map)
date: 2019-06-30 14:52:26
tags:
- set
- map
categories: - 前端
1. set
set叫做集合,是一种新的数据类型,这种数据类型跟数组很类似,但是它的值是无序的,并且set没有重复值。
set可以通过Set()
这个构造函数来创建
let s = new Set([1, 2, 3, 4])
console.log(s)
可以看出,set中的键和值是相同的。
由于set内没有重复值,利用这个特点可以方便的实现数组的去重:
let arr = [1, 1, 2, 2, 3, 3]
let s = new Set(arr)
let newArr = [...s] //这里利用了解构赋值
console.log(newArr) //(3) [1, 2, 3]
set还有很多的属性和方法,都比较简单,具体可以参考Set
2. Map
Map,映射,这种数据类型保存的是键值对,和对象Object很相似,不同的在于Object的键必需是字符串类型,而Map的键没有要求数据类型。此外,map具有可迭代属性,因此Map可以直接用于for...of
语句,而普通定义的对象需要考虑其是否具有迭代函数iterator。
map的一个重要作用也是应用在对象属性的私有化上面,举一个例子:
const Student = (function(){
let _score = 0;//自执行函数的内部变量实现对象的私有属性
function S(name, score) {
this.name = name;
_socre = score;
}
return S;
})();
let s1 = new Student('john', 100);
let s2 = new Student('marry', 90);
console.log(s1);
console.log(s2);
在上面这里例子中,创建了一个student对象,student对象有两个属性name和score。我们希望name属性是公开的,可以任意访问和修改,但是我们不希望score也能够被随意访问和修改,要不然有可能每一个学生的成绩都是100分了,如果有一些的学生成绩如果是1000分或者-100,那就更糟糕了,所以我们希望score是对象的一个私有属性,这里的做法是通过自执行函数来创建对象,其中对象的私有属性通过函数的内部变量来实现。打印实例化后的两个对象s1和s2:
上面这个例子可以实现对象属性的私有化,但是这个例子有一些问题,具体原因在于对象s1和s2都共用了score这个私有化属性,为了说明问题,修改一下上面的例子:
const Student = (function(){
let _score = 0;//自执行函数的内部变量实现对象的私有属性
function S(name, score) {
this.name = name;
_socre = score;
}
S.prototype.getScore = function () {
return _score;
}
S.prototype.setScore = function (num) {
_score = num;
}
return S;
})();
let s1 = new Student('john', 100);
let s2 = new Student('marry', 90);
s1.setScore(98);
s2.setScore(80);
console.log(s1.getScore())
console.log(s2.getScore())
我们在S
的原型上加上getScore
方法和setScore
方法,分别用来设置score和访问score,但是在给s1设置98分,给s2设置80分后,发现最终s1和s2的分数都是80分,产生这个错误的原因在于s1和s2共用了自执行函数里的_score
变量。要解决这种问题就需要改写自执行函数的_score
变量,最好是一种对象与成绩一一对应的数据结构,这个时候map
的作用就体现了,因为,在map
中,对象可以作为键,因此可以实现对象与键值的一一对应。改写上面的这个例子:
const Student = (function(){
let _score = new Map()
function S(name, score) {
this.name = name;
_score.set(this. score);
}
S.prototype.getScore = function () {
return _score.get(this)
}
S.prototype.setScore = function (num) {
_score.set(this, num)
}
return S;
})();
let s1 = new Student('john', 100);
let s2 = new Student('marry', 90);
s1.setScore(98);
s2.setScore(80);
console.log(s1.getScore())
console.log(s2.getScore())
这样改写以后就能够正常访问到s1和s2对象的私有需要保护的属性。