Symbol

Symbol是独一无二的,可以当作永远不会重复的字符串。

Symbol的应用场景

例如存储一个班级中的成绩,有两个重名的人,如果直接对对象中的两个同名键名赋值,则后面的会覆盖前面的,使用Symbol可以解决同名字符串冲突的问题。

Symbol的声明

  1. let a = Symbol('这是a');//括号内是他们的描述
  2. let b = Symbol.for('这是b');
  3. a = 'hello';//为Symbol变量赋值
  4. console.log(a.description);//使用这个api访问描述

1.Symbol.for():有时,我们希望重新使用同一个 Symbol 值,Symbol.for方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
2.这两个方法创建Symbol的不同点,直接创建时,就算使用相同的描述字符串,创建出的变量也是不一样的,但是,使用Symbol.for方法创建的变量,会优先使用同一描述的变量,因此如果对同一描述创建10次变量,则直接创会创建出10个不同的变量,互等为false,Symbol.for会创建10个不同名的变量,但是他们互等为true。

Symbol作为属性名

let mySymbol = Symbol();

// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';

// 第二种写法
let a = {
  [mySymbol]: 'Hello!'
};

// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上写法都得到同样结果
a[mySymbol] // "Hello!"

注意,Symbol 值作为对象属性名时,不能用点运算符。因为点运算符后面总是字符串,所以不会读取Symbol指代的那个值。因此,在对象中定义时,也要用[]包裹。
注意,Symbol值定义的属性,是不可遍历的,需要使用Object.getOwnPropertySymbols(obj)遍历Symbol属性,使用Reflect.ownKeys(obj)遍历所有属性(包括Symbol和普通类型定义的属性)。

Set

Set的声明

let set = new Set([1,2,3,4,5]);、
let set2 = new Set('abcde');//打印出{'a','b','c','d','e'},字符串会被拆分开
set.add(1);//无变化,因为set中的元素不能重复
set.add('1');//类型不一样可以添加
console.log(typeof set);//object

使用typeof运算符打印出object字符串,但是他与object是不同的,object中的键名只有字符串,因此键名为1和’1’会被覆盖。

Set的一些api

set.size;//set的长度
set.clear();//清空set
set.delete();//删除某一个元素,返回值为true,如果不存在该元素返回false,可以判断是否存在
set.values();//查看元素
set.has();//检测元素
set.add();//加入元素

Set与数组类型转换

转化成数组 Array.from(set) \ […set] ,可以通过数组进行一些条件判断,数组也可以通过转化成Set类型来删除重复的元素,因为set不允许元素的重复。

Set元素的查看与遍历

set.values()
set.keys()
set.entries()
set.forEach()
for…of

Set的一些应用

1.可以使用set来筛选重复的关键词
2.实现交集,并集,差集

[...set1,...set2];//并集
let set1 = new Set([1, 2, 3, 4, 5]);
      let set2 = new Set([3, 4, 5, 6, 7]);
      let c = new Set(
        [...set1].filter(function (item) {
          return !set2.has(item);//加上!是差集,去掉感叹号则是计算交集
        })
      );//{1,2}
      console.log(c);//差集

WeakSet

weakset保存的是引用类型的变量,在set类型的api中,weakset可以使用的是add、delete、has。
为什么会这样呢?

WeakSet的弱引用特性

WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不
再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
这是因为垃圾回收机制依赖引用计数,如果一个值的引用次数不为0,垃圾回收机制就不会释放这块内存。结束使用该值之后,有时会忘记取消引用,导致内存无法释放,进而可能会引发内存泄漏。WeakSet 里面的引用,都不计入垃圾回收机制,所以就不存在这个问题。因此,WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。
由于上面这个特点,WeakSet 的成员是不适合引用的,因为它会随时消失。另外,由于 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。

Map

Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

Map的声明

const a = new Map([['name1',1],['name2',2]]);
//可以接收一个具有Iterator接口,且每一个成员都是'键与值'特征的数组的数据结构
const b = new Map(a)
const c = new Map(new Set([['name1',1],['name2',2]]))

Map的api

const map = new Map();
map.size
map.set(键,值);//没有则新建,有则更新
map.get(键);
map.has(键);
map.delete(键);
map.clear()

Map的一些特性

  1. 键是引用类型的数据的时候,需要地址相同才可以得到同一个值
  2. 如果键是简单类型的值,那么就需要值严格相等(===),例如0和-0,但是有一个例外NaN虽然不等于自身,但是被视为同一个键

    Map的遍历

    map.keys()
    map.values()
    map.entries()
    map.forEach(value,key,map)

    Map与其他数据结构的转化

  3. 数组

    参数传入数组可以直接转化成Map
    […map]使用扩展运算符转化成数组,扩展运算符用的是for..of

  4. 对象

    参数中传入Object.entries()的返回值,返回值是键值对的数组
    map使用for..of循环遍历来对对象进行赋值

  5. JSON

    转化成JSON,如果键都是字符串,就转化成对象,然后转化成JSON,如果不全是
    字符串,就转化成数组,
    JSON转化成map,如果是对象json,就使用循环,如果是数组,且满足map要求,
    就可以使用new Map()

    WeakMap

    weakmap与weakset类似,都是弱引用特性,键(只有键)引用的数据如果不被其他引用了,那么weakmap中的键和值都会消失
    另外,weakmap只会接收对象作为键,其他的数据都不可以作为键,另外null也不可以

一个应用场景是往dom元素的键,对应相应的值,另外可以用于部署私有属性,将类本身作为键,这样类的引用消失了,私有属性也消失了,总的来说就是用来防止内存的泄漏

wekmap的api只有get、set、delete、has四个方法,没有遍历方法以及size属性