ES6语法常用包括set weakSet map weakSet(vue3响应式原理用的就是这个存储类型)

96 阅读5分钟

Set

类似于数组** 它的内部元素不能重复 普通数组内部时可以重复的** 创建Set通过new。 可以把Set看成一个构造函数 使用方式

  • 可以数组去重
  • size属性 返回元素个数
  • delect 删除元素
  • has 是否包含
  • clear 清楚
  • forEach for(const item of set) 遍历
const set = new Set()
set.add(10)
set.add(20)
set.add({})
set.add({})
console.log(set)
里面会有两个对象 值是空的。 因为这是保存了两个内存地址

const obj={}
set.add(obj)
set.add(obj)

里面有2个对象 因为这是一个内存地址 (引用的是一个内存地址)
console.log(set)

1.通过循环数组去重
const arr = [10,20,30,10]
const arrNew=[]
for(const item of arr){
 if(arrNew.indexOf(item) !==-1){
  arrNew.push(item)
 }
}

2. 通过set方式去重复
const arrSet = new Set(arr)
const newArr1 = Array.from(arrSet)
const newArr2 = [...arrSet]

WeakSet

他和set基本上一致 区别就是 只能存放 对象类型 **存放的类型为弱类型 **如果没有其他对他使用 它将会被GC(V8垃圾回收) 将被回收内存空间 在正常创建的对象他是一个强引用指向一个内存空间 如果不给他设为null GC就不会去回收它 它是没有遍历的 也没有clear清除的 所以没有办法一个一个获取到

1.const pwset = new WeakSet();
class Person {
  constructor() {
    pwset.add(this);
  }
  running() {
    if (!pwset.has(this)) {
      throw new Error('不能通过非构造方法去调用它');
    }
    console.log(running);
  }
}
const p = new Person();
p.running();

p.running.call({ name: '123' });

Map

也是存储映射关系 (key(字符串/symbol) :value)

const obj2 = {age:12}
const ibfo={
  [obj1]:'111',
  [obj2]:'222'
}
// 他会把obj1先转换成字符串 对象转换字符串就是‘[object object]’
map 可以用对象当key
const map = new Map()
map.set(obj1,'aaa')

map.set(obj1, 'aaa');

const map2 = new Map([
  [obj1, '111'],
  [obj2, '222'],
]);

map.get(obj1);
map.has(obj1);
map.delete(obj);
map.clear();
map.forEach((value, key) => {});

// 利用结构赋值 解析遍历出来的是数组 直接获取数组内容
for (const [key, value] of map2) {
  console.log(key, value);
}

WeakMap

只能存放对象 并且也是弱引用(vue3响应式原理用的就是它) **vue2 响应式 template

{{name}}
最终都会变成render函数** **如果name发生改变 就会重新执行这块的render函数 就会用最新的name 然后生成最新的虚拟节点node节点 vnode节点 最后渲染到界面上面**
function obj1Name(){
  console.log('obj1里面name发生改变')
}

function obj2Name(){
  console.log('obj2里面name发生改变')
}

// 创建一个weakMap 因为如果有一天obj不想用了 因为weakMap是一个弱引用类型 所以他会自动帮你消除里面添加的元素 所以不会用map
const weakMap = new weakMap();

对obj1Name收集的数据结构
const map1 = new map()
map1.add('name',[obj1Name,obj2Name])
 weakMap.add(obj,map1)
 
 如果obj里面的name发生了改变
 可以通过Proxy/Object.defineProxy来进行监听是否改变
 obj.name='sdad'
这个时候监听到了改变
const targeMap = weakMap.get(obj)
const funs= targeMap.get('name')

依次执行存放的name监听函数
funs.forEach(value=>{
  value()
})


const name1 = [ '333','asd','caj']
// 以前通过获取索引值判断是否包含  他没发判断NAN的
if(name1.indexOf('abc')!==-1){
}
// includes(值,从哪个索引值开始)    他可以判断数组里面是否包含NAN的
if(name1.includes('name',2)){

}
// 指算运算符
// 3的3次方
const num= 3**3

模版字符串

首先,我们会使用 符号来编写字符串,称之为模板字符串; 其次,在模板字符串中,我们可以通过 ${内容} 来嵌入动态的内容; 标签模版字符串 如果我们使用标签模板字符串,并且在调用的时候插入其他的变量: 模板字符串被拆分了; 第一个元素是数组,是被模块字符串拆分的字符串组合; 后面的元素是一个个模块字符串传入的内容; 这种写法在 react 里有个 styled-components 组件库用的特别多 **react 开发 特性 all in js 所有代码都可以在 js 上面写 内部原理就是标签模版字符串 **

// 第一个参数依然是模块字符串中整个字符串, 只是被切成多块,放到了一个数组中
// 第二个参数是模块字符串中, 第一个 ${}
function foo(m, n, x) {
  console.log(m, n, x, '---------');
}

// foo("Hello", "World")
// 另外调用函数的方式: 标签模块字符串
// foo``

// foo`Hello World`
const name = 'why';
const age = 18;
// ['Hello', 'Wo', 'rld']
foo`Hello${name}Wo${age}rld`;

// function style(m) {
//   return m;
// }
// const red = red;
// style`color:{${red}}`;

函数参数的默认值

在es5时这么给默认值的 但是穿0和null 不会给默认值

function foo(m,n){
  m=m||'a'
  n=n||'b'
}

在es6中
function foo(m='a',n='b'){}
对象参数 和默认值以及解构 
function ({name,age} = {name:'why' , age=18 }){ } 
function ({name='xsh',age=19} = {}){ }

有默认值的姓参最好放到最后 有默认值的函数length属性 (函数的长度是参数的个数) 从有默认值开始一直都不算参数长度了

函数的剩余参数

arguments 也是函数可以获取参数的 剩余参数和arguments的区别 1.剩余参数包含哪些没有对应形参的实参,而arguments对象包含了传给函数的所有实参 2.arguments对象不是一个真正的数组 不能遍历。。。 而剩余参数是一个真正的数组 可以进行数组所有操作 3.arguments是早期ECMA 为了方便获取所有参数提供的一个数据结构 现在由es6的剩余参数来代替了

箭头函数的补充 箭头函数没有显示原型 所以不能当成一个构造函数 也不能通过new调用 展开运算符 可以展开数组 也可以展开字符串 构建对象的时候也可以使用

const info={name:'xsh',age:18}
const obj ={...info,add:'11'}

其实他就是一个浅拷贝 在内存空间 会指向同一个内存地址 修改任何其实都是修改同一个指向的内存地址

数字的进制

const num1 = 100 // 十进制

// b -> binary
const num2 = 0b100 // 二进制
// o -> octonary
const num3 = 0o100 // 八进制
// x -> hexadecimal
const num4 = 0x100 // 十六进制

console.log(num1, num2, num3, num4)

// 大的数值的连接符(ES2021 ES12)
const num = 10_000_000_000_000_000
console.log(num)

Symbol (es6新增的数据类型)

1. 在es6之前 对象的属性名(key value)用的都是hashMap 2. 对象的属性名都是字符串类型 所以很容易造成属性名的冲突 3. 可以通过Symbol生成一个独一无二的值 他其实是一个函数 4. 即使多次创建 他每次的值都是不同的 也可以传入一个描述

const s1 = Symbol('aaa')
s1,description // aaa
const obj = {
  [s1]:'cba'
}
obj[s3]='nba'
Object.defineProperty(obj,s1,{})

注意:不可以用.语法来获取 只能用obj[s1] 再使用Symbol作为key的属性名 在遍历以及Object.keys中获取不到每一个值 需要通过Object.getOwnProperSymbols()方法来获取所有的值 在es6以后对象的属性值可以用字符串或者Symbol

const sa =Symbol.for('aaa')
const sc =Symbol.for('aaa')
获取对应的key
Symbol.keyfor(sa)