关于ES6新特性的总结
创始人
2024-06-01 06:15:35
0

目录

  • 1.let & const
  • 2.解构赋值
  • 3.模板字符串
  • 4.简化对象写法
  • 5.箭头函数
  • 6.函数参数的默认值设置
  • 7.rest参数
  • 8.扩展运算符
  • 9.Symbol
    • Symbol特点
    • 创建Symbol
    • Symbol使用场景
    • Symbol内置值
  • 10.迭代器
  • 11.生成器
  • 12.Promise
    • 基本使用
    • Promise封装读取文件
    • Promise封装ajax
    • Promise.prototype.then方法
    • 通过链式调用实现按顺序读取文件
    • Promise对象catch方法
  • 13.set(集合)
    • 集合的属性和方法
    • set的应用
  • 14.Map

1.let & const

1) let,作用与var类似,用于声明变量
特性:

  1. let 不能重复声明变量,var 可以重复声明变量;
  2. 块级作用域,es5中存在全局作用域、函数作用域、eval作用域;es6中引入了块级作用域,let声明的变量在块级作用域{}内有效
  3. let声明的变量不存在var的变量提升问题

举个例子:



Document

点击切换颜色

1

2

3

2) const 用于声明常量
注意事项:

  1. 一定要赋初始值
  2. 一般常量使用大写(属于编程规范)
  3. 常量值不能修改
  4. 存在块级作用域
  5. 对于数组和对象的元素修改,不算做对常量的修改,不会报错(因为引用数据类型保存的是内存地址,所以声明数组和对象时可以使用const声明,以此保证其保存的内存地址不变)

2.解构赋值

ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值

1) 数组的解构

const Web = ['html', 'css', 'javascript']
let [tool1, tool2, tool3] = Webconsole.log('tool1-----', tool1) // html
console.log('tool2-----', tool2) // css
console.log('tool3-----', tool3) // javascript

2) 对象的解构

const liMing = {name: 'liMing',age: '22',tell: function(){console.log(`I am liMing`)}
}let {name, age, tell} = liMingconsole.log(name) // 'liMing'
console.log(age) // '22'
console.log(tell) // f(){...}
tell() // I am liMing

3.模板字符串

特性:

  1. (反引号)内容中可以直接出现换行符,’ '和" "中则不可以,出现会报错
  2. 可以直接进行变量拼接

4.简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法(在属性名和变量名相同的情况下),这样的书写更加简洁

let name = 'LiMing'
let tell = function(){console.log('I am LiMing')
}const liMing = {name,tell,sayHi(){console.log('hello')}
}// 等效于
// const liMing = {
//     name: name,
//     tell: tell,
//     sayHi: function(){
//         console.log('hello')
//     }
// }console.log(liMing)
liMing.tell()
liMing.sayHi()

5.箭头函数

function声明的区别:

1.箭头函数this是静态的。

  • 箭头函数内的this指向上层对象;始终指向函数声明时所在作用域下的this的值,无法被call改变
  • 普通函数内的this指向调用其函数的对象
function getName(){console.log(this.name)
}let getName2 = ()=>{console.log(this.name)
}// 设置window对象的name属性
window.student = 'LiMing'
const student = {name: 'HanMei'
}// 直接调用
getName() // LiMing
getName2() // LiMing// call方法调用
getName.call(student) // HanMei
getName2.call(student) // LiMing

2.箭头函数不能作为构造函数实例化对象

let Person = (name, age)=>{this.name = namethis.age = age
}
let me = new Person('LiMing', 20) // 报错:Uncaught TypeError: Person is not a constructor

3.箭头函数不能使用arguments变量,但是可以使用....rest

let fn = ()=>{console.log(arguments)
}fn(1, 2, 3) // 报错:Uncaught ReferenceError: arguments is not definedlet fn2 = (...rest)=>{console.log(...rest)
}fn2('a','b','c') // a b c

4.箭头函数的简写
① 当形参有且只有一个的时候,可以省略()
② 当代码体只有一条语句的时候,可以省略{},此时return必须省略,而且语句的执行结果就是函数的返回值

// 当形参有且只有一个的时候,可以省略`()`
let add = n => {return n + n
}console.log(add(9))// 当代码体只有一条语句的时候,可以省略`{}`,此时`return`必须省略,而且语句的执行结果就是函数的返回值
let pow = n => n*nconsole.log(pow(9))

5.箭头函数的例子
箭头函数适合与this无关的回调,比如定时器setTimeout(()=>{...}, 2000)、数组的方法回调arr.filter((item)=>{...})
不适合与this有关的回调,比如dom元素的事件回调ad.addEventListener('click', function(){...}、对象内的方法定义{name: 'LiMing', getName: function(){this.name}}
例1:

// 需求-1 点击div 2s后颜色变红// 获取元素
let ad = document.getElementById('ad')
// 绑定事件
ad.addEventListener('click', function(){setTimeout(function(){console.log(this) // 定时器里的this指向windowthis.style.background = 'brown' // 报错}, 2000)
})//解决方案1
// ad.addEventListener('click', function(){
//     // 保存this的值
//     let _this = this // _this指向ad
//     setTimeout(function(){
//         console.log(_this) 
//         _this.style.background = 'brown'
//     }, 2000)
// })// 解决方案2
// ad.addEventListener('click', function(){
//     setTimeout(()=>{
//         console.log(this) 
//         this.style.background = 'brown' // this指向函数声明时所在作用域下this的值 即ad
//     }, 2000)
// })

例2:

// 需求-2 从数组中返回偶数的元素
const arr = [1, 6, 9, 10, 100, 25]
const result = arr.filter(function(item){if(item %2 === 0){return true}else{return false}
})// 可以用箭头函数
// const result = arr.filter(item => {
//     if(item % 2 === 0){
//         return true
//     }else{
//         return false
//     }
// })
// 还可以简写为
// const result = arr.filter(item => item % 2 === 0)console.log(result)

6.函数参数的默认值设置

ES6允许给函数参数赋初始值

function add(a, b, c=10){ // 具有默认值的参数,一般位置要靠后return a + b + c
}
console.log(add(1,2,))

可以与解构赋值一起使用

function connect({host='127.0.0.1', port, username, password}){console.log(host, port)console.log(username, password)
}connect({port: 3306,username: 'root',password: 'root',
})

7.rest参数

ES6引入rest参数,用于获取函数的实参,用来代替arguments

// ES5获取实参的方式
function printStudent(){console.log(arguments) // arguments为一个对象
}
printStudent('LiMing','HanMeimei')// ES6获取实参的方式
function printFriend(friend1, friend2, ...rest){ // rest参数必须放在形参列表最后,否则会报错console.log(friend1) console.log(friend2) console.log(rest) // 得到一个数组,可以使用数组api
}
printFriend('小猫','小狗','兔子','鸭子')
// 小猫
// 小狗
// ['兔子','鸭子']

8.扩展运算符

...能将「数组」转为逗号分隔的「参数序列」
注:虽然形式与rest参数类似,但是rest参数是用在函数定义时的形参位置,扩展运算符是用在函数实际调用时的实参位置

const STUDENTS = ['小明','小芳','小红']
function printStudent(){console.log(arguments)
}printStudent(STUDENTS) // 参数为一个数组,数组内包含3个元素
printStudent(...STUDENTS) // 参数为3个元素

应用场景:

  1. 数组的合并
const STUDENTS1 = ['小明','小芳','小红']
const STUDENTS2 = ['小吴', '小王']// es5写法
const STUDENTS_ES5 = STUDENTS1.concat(STUDENTS2)
// es6写法
const STUDENTS_ES6 = [...STUDENTS1, ...STUDENTS2]console.log('es5------',STUDENTS_ES5)
console.log('es6------',STUDENTS_ES6)
  1. 数组的克隆
const STUDENTS1 = ['小明','小芳','小红']const PUPIL = [...STUDENTS1] // 注意:如果数组内元素是引用类型,拷贝的是内存地址,为浅拷贝
console.log('PUPIL----',PUPIL)
  1. 将伪数组转为真正的数组
const divs = document.querySelectorAll('div')
console.log(divs) // 此处得到的divs实际是一个对象const divsArr = [...divs] // 将其转为真正的数组,从而可以使用数组的api譬如filter、map
console.log(divsArr)

9.Symbol

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第7种数据类型,是一个类似字符串的数据类型

Symbol特点

  1. Symbol的值是唯一的,用来解决命名冲突的问题
  2. Symbol值不能与其他数据进行运算,也不能与自己进行运算,譬如+、-、*、/、比较运算
  3. Symbol定义的对象属性不能使用for…in遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

创建Symbol

  1. 通过let s2 = Symbol('张三') 的方式创建Symbol,'张三’作为Symbol描述,作用相当于注释,这种方式创建的Symbol,即使传入的描述一致,但实际返回的值是不同的
// 创建Symbol
let s = Symbol()
console.log(s,typeof s) // Symbol() "symbol"let s2 = Symbol('张三') // '张三'作为Symbol描述,作用相当于注释
let s3 = Symbol('张三') // 即使传入的描述一致,但实际返回的值是不同的
console.log(s2 === s3) // false
  1. 通过Symbol.for()创建Symbol,这种方式创建Symbol,传入的描述一致,实际返回的值也一致,可以得到唯一的Symbol
// Symbol.for创建Symbol
let s4 = Symbol.for('张三')
let s5 = Symbol.for('张三')
console.log(s4 === s5) // true

Symbol使用场景

给对象添加属性和方法。由于Symbol值具有唯一性,所以可以很安全地把属性和方法加入对象中,如下所示

let game = {up: 'upp',down: 'doown'
}let methods = {up: Symbol(),down: Symbol(),
}// 添加方法
game[methods.up] = function(){console.log('up up up')
}
game[methods.down] = function(){console.log('down down down')
}console.log('game----', game)
// 调用
game[methods.up]()
let youxi = {name: '狼人杀',[Symbol('say')]: function(){ // 此处不能直接写 Symbol('say'): function(){...},因为Symbol('say')是动态的,和上面固定的'name'不一样console.log('发言')}
}

Symbol内置值

ES6除了定义自己使用的Symbol值以外,还提供了11个内置的Symbol值,指向语言内部使用的方法,比如

  1. Symbol.hasInstance
    当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
 class Person{static [Symbol.hasInstance](param){console.log('param----', param)console.log('检测类型')}}let o = {}console.log(o instanceof Person)// param---- {}// 检测类型// false
  1. Symbol.isConcatSpreadable
    对象的Symbol.isConcatSpreadable属性等于一个bool值,表示该对象用于Array.prototype()时,是否可以展开
const arr1 = [1,2,3]
const arr2 = [4,5,6]
arr2[Symbol.isConcatSpreadable] = false // arr2不可展开
const arr = arr1.concat(arr2)
console.log(arr) // [1,2,3,[4,5,6]]
  1. Symbol.unscopables
    该对象指定了使用with关键字时,哪些属性会被with环境排除
  2. Symbol.match
    当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值
  3. Symbol.replace
    当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值
  4. Symbol.search
    当该对象被str.search(myObject)方法调用时,会返回该方法的返回值
  5. Symbol.split
    当该对象被str.split(myObject)方法调用时,会返回该方法的返回值
  6. Symbol.iterator
    对象进行for ... of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器
  7. Symbol.toPrimitive
    该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值
  8. Symbol.toStringTag
    在该对象上调用toString方法时,返回该方法的返回值
  9. Symbol.species
    创建衍生对象时,会使用该属性

10.迭代器

迭代器(iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署iterator接口,就可以完成遍历操作

ES6创造了一种新的遍历命令for...of循环,iterator接口主要供for...of消费
注:for...of遍历的是键值,for...in遍历的是键名
for...of不能对属性值进行修改,forEach()可以

原生具备iterator接口的数据(可用for...of遍历)

  • Array
  • Arguments
  • Set
  • Map
  • String
  • TypedArray
  • NodeList

工作原理:

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
  3. 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
  4. 每调用next方法返回一个包含valuedone属性的对象,done属性表示遍历是否结束
const food = ['鱼香肉丝','糖醋里脊','酸菜鱼']
for(let item of food){console.log(item)
}let iterator = food[Symbol.iterator]()console.log(iterator.next()) // {value: "鱼香肉丝", done: false}
console.log(iterator.next()) // {value: "糖醋里脊", done: false}
console.log(iterator.next()) // {value: "酸菜鱼", done: false}
console.log(iterator.next()) // {value: undefined, done: true} true 表示遍历已经结束

注:需要自定义遍历数据的时候,要想到迭代器

迭代器应用-自定义遍历数据(即自己手动实现一个迭代器)

// 声明一个对象
const school = {name: '三中',students: ['LiMing','HanMeimei','WangFang',],[Symbol.iterator](){// 声明一个索引变量let index = 0return {next: ()=>{if(index < this.students.length){// if(index < 3){const result = {value: this.students[index], done: false}// 下标自增index++// 返回结果return result}else{return {value: undefined, done: true}}}}}
}// 遍历这个对象
for(let item of school){console.log(item)
}

11.生成器

生成器本身是一个特殊的函数,生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数不同

  • 执行生成器函数,返回的是一个迭代器对象,通过iterator.next()调用执行函数内语句
function * gen(){console.log('hello generator')
}
let iterator = gen() // 返回的是一个迭代器对象
// console.log(iterator)
// 通过.next()调用执行函数内语句
iterator.next() // hello generator
  • yield是函数代码的分隔符,结合调用iterator.next()方法,实现函数gen1的语句的分段执行
function * gen1(){console.log('--- 1 ---')yield '耳朵' // 函数代码的分隔符console.log('--- 2 ---')yield '尾巴'console.log('--- 3 ---')
}let iterator1 = gen1()
iterator1.next() // --- 1 ---
iterator1.next() // --- 2 ---
iterator1.next() // --- 3 ---
// 通过调用.next()方法,实现函数gen1的语句的分段执行
  • 使用for...of遍历函数执行后返回的迭代器对象,每一次遍历的itemyield后的表达式或者自变量的值
function * gen1(){yield '耳朵' // 函数代码的分隔符yield '尾巴'
}// 遍历,每一次遍历的item为yield后的表达式或者自变量的值
for(let item of gen1()){console.log(item)
}
// 执行结果:
// 耳朵
// 尾巴// 注:next调用和for...of调用同时存在,只会支持最先的一个
  • 生成器函数的参数传递
function * gen(args){console.log(args) // 'aaa'let one = yield 111console.log(one) // 'bbb'let two = yield 222console.log(two) // 'ccc'let three = yield 333console.log(three)
}// 执行生成器函数获取迭代器对象
let iterator = gen('aaa')console.log(iterator.next()) // {value: 111, done: false}
// next方法可以传入实参,传入的实参会作为上一个yield后返回的结果
console.log(iterator.next('bbb')) // {value: 222, done: false}
console.log(iterator.next('ccc')) // {value: 333, done: false}
console.log(iterator.next('ddd')) // {value: undefined, done: true}
  • 生成器函数实例1:
    1s后控制台输出111 --> 2s后控制台输出222 --> 3s后控制台输出333 ==> 总计耗时6s
   // 异步编程,如文件操作、网络请求、数据库操作// 1s后控制台输出111 --> 2s后控制台输出222 --> 3s后控制台输出333  ==> 总计耗时6s// 用生成器函数实现function one (){setTimeout(()=>{console.log(111)iterator.next()}, 1000)}function two (){setTimeout(()=>{console.log(222)iterator.next()}, 2000)}function three (){setTimeout(()=>{console.log(333)}, 3000)}function * gen(){yield one()yield two()yield three()}let iterator = gen()iterator.next()// 以下为回调地域做法// setTimeout(()=>{//     console.log(111)//     setTimeout(()=>{//         console.log(222)//         setTimeout(()=>{//             console.log(333)//         }, 3000)//     }, 2000)// }, 1000)
  • 生成器函数实例2:
    模拟获取 用户数据 --> 订单数据 --> 商品数据
// 模拟获取 用户数据 --> 订单数据 --> 商品数据
function getUsers(){setTimeout(()=>{let data = '用户数据'iterator.next(data) // 相当于把得到的数据,传回users}, 1000)
}function getOrders(){setTimeout(()=>{let data = '订单数据'iterator.next(data)}, 2000)
}function getGoods(){setTimeout(()=>{let data = '商品数据'iterator.next(data)},3000)
}// 定义生成器函数
function * gen (){let users = yield getUsers()console.log(users) // 用户数据let orders = yield getOrders()console.log(orders) // 订单数据let goods = yield getGoods()console.log(goods) // 商品数据
}// 调用生成器函数,获取迭代器对象
let iterator = gen()
iterator.next()

12.Promise

PromiseES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

  1. Promise构造函数:Promise(excutor){}
  2. Promise.prototype.then方法
  3. Promise.prototype.catch方法

基本使用

// 实例化Promise对象
const p = new Promise(function(resolve, reject){setTimeout(()=>{let data = '数据库中的用户数据'// resolve(data)let err = '数据读取失败'reject(err)},1000)
})p.then((value)=>{console.log('enter success')console.log(value)
},err=>{console.log('enter failed')console.log(err)
})

Promise封装读取文件

// 1.引入fs模块 fileSystem 文件系统
const fs = require('fs')// 2.调用方法读取文件
// fs.readFile('./resource/file.md', (err, data)=>{ // data是一个buffer,用来存储2进制文件,用法跟数组类似
//     // 如果失败,抛出错误
//     if(err) throw err
//     // 如果成功,读取文件
//     console.log(data.toString())
// })// 3.使用promise封装
const p = new Promise(function(resolve, reject){fs.readFile('./resource/file.md', (err,data)=>{if(err){reject(err)}else{resolve(data.toString())}})
})
p.then((value)=>{console.log(value)
},(reason)=>{console.error(reason)
})

Promise封装ajax

// 接口地址:https://api.apiopen.top/getJoke
// 原生ajax发送请求
// // 1.创建对象
// const xhr = new XMLHttpRequest()// // 2.初始化
// xhr.open('GET', 'https://api.apiopen.top/getJoke')// // 3.发送
// xhr.send()// // 4.绑定事件
// xhr.onreadystatechange = function(){
//     // 判断阶段
//     if(xhr.readyState === 4 ){
//         // 判断响应状态码
//         if(xhr.status >= 200 && xhr.status < 300){
//             // 如果状态码为成功,打印返回结果
//             console.log(xhr.response)
//         }else{
//             // 如果失败
//             console.error(xhr.status)
//         }
//     }
// }// promise封装发送ajax请求
const p = new Promise((resolve, reject)=>{const xhr = new XMLHttpRequest()xhr.open('GET', 'https://api.apiopen.top/getJoke')xhr.send()xhr.onreadystatechange = function(){if(xhr.readyState === 4){if(xhr.status >=200 && xhr.status < 300){resolve(xhr.response)}else{reject(xhr.status)}}}
})
p.then((value)=>{console.log(value)
},(reason)=>{console.log(reason)
})

Promise.prototype.then方法

then方法的返回结果,依然是一个promise对象,其状态的成功或失败,由then里的回调函数的执行结果决定

  • 如果回调函数中返回的结果是非promise类型的属性,状态为成功,且return的结果就是该promise成功后resolve的值
    注: 如果没有return,则默认返回undefined,所以状态依然为成功
  • 如果返回的结果是promise对象,则该promise对象的状态就是then返回的promise对象的状态
  • 如果是抛出一个值(如一个错误),则状态为失败
const p = new Promise((resolve, reject)=>{setTimeout(()=>{resolve('用户数据')// reject('出错啦')}, 1000)
})const result = p.then((value)=>{ // p执行resolve后,状态为成功,执行第一个函数console.log(value )// 1.返回非promise对象的情况// return 233 // 233// 2.返回promise对象return new Promise((resolve, reject)=>{resolve('ok') // 状态为成功,值=ok// reject('error!!') // 状态为失败})// 3.抛出错误// throw new Error('error!!!')
},(reason)=>{ // p执行reject后,状态为失败,执行第二个函数console.warn(reason)
})// then方法的返回结果,依然是一个promise对象,其状态的成功或失败,由then里的回调函数的执行结果决定
console.log(result)

then方法的这个特性,决定了then方法可以进行链式调用

const p = new Promise((resolve, reject)=>{setTimeout(()=>{resolve('用户数据')// reject('出错啦')}, 1000)
})// 链式调用
p.then((value)={// ...
}).then((value)=>{// ...
})

通过链式调用实现按顺序读取文件

// 1.引入fs模块 fileSystem 文件系统
const fs = require('fs')// 使用传统方式实现 读取文件1 => 读取文件2 => 读取文件3
// fs.readFile('./resource/file1.md', (err, data)=>{
//     let data1 = data.toString()
//     fs.readFile('./resource/file2.md', (err,data)=>{
//         let data2 = data.toString()
//         fs.readFile('./resource/file3.md', (err,data)=>{
//             let data3 = data.toString()
//             let data_all = {data1,data2,data3}
//             console.log(data_all)
//         })
//     })
// })// 使用promise方式实现 读取文件1 => 读取文件2 => 读取文件3
const p = new Promise((resolve, reject)=>{fs.readFile('./resource/file1.md', (err,data)=>{resolve(data)})
})p.then((value) => {return new Promise((resolve, reject)=>{fs.readFile('./resource/file2.md',(err,data)=>{let data_all =  {data1: value.toString(),data2: data.toString()}resolve(data_all)})})
}).then((value)=>{return new Promise((resolve,reject)=>{fs.readFile('./resource/file3.md', (err,data)=>{value.data3 = data.toString()resolve(value)})})
}).then(value=>{console.log(value)//  { data1: '# 这是文件1', data2: '# 这是文件2', data3: '# 这是文件3' }
})

Promise对象catch方法

用于指定promise对象失败的回调

const p = new Promise((resolve,reject)=>{setTimeout(()=>{// 设置p对象的状态为失败reject('opps error')},1000)
})// p.then((value)=>{}, (reason)=>{
//     console.error(reason)
// })// 相当于then里面的第二个回调函数
p.catch((reason)=>{console.warn(reason)
})

13.set(集合)

ES6提供了新的数据结构set(集合),本质上是一个对象。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用「扩展运算符」和for...of进行遍历

集合的属性和方法

size,返回集合的元素个数
add,增加一个新元素,返回当前集合
delete,删除元素,返回Boolean
has,检测集合中是否包含某个元素,返回Boolean

let s = new Set(['风声','雨声','读书声','风声']) // 可以接受可迭代数据,一般传入数组
// '风声','雨声','读书声'let size = s.size // 查看元素个数
let has = s.has('读书声') // 检测是否含该元素 true
s.add('水声') // 添加元素
s.delete('读书声') // 删除元素
let has2 = s.has('读书声') // 检测是否含该元素 false// 遍历集合
for(let item of s){console.log(item)
}
s.clear() // 清空集合console.log(s, has,has2, typeof s)

set的应用

数组去重

let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
// 数组去重
let result = [...new Set(arr)]
console.log(result) // [1, 2, 3, 4, 5]

求交集

let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
let arr2 = [4, 5, 6, 5, 6]// 求交集
let result = [...new Set(arr)].filter(item => { // 对arr去重并进行遍历let s2 = new Set(arr2) // 将arr2变为元素不重复的集合if(s2.has(item)){ // 如果元素存在s2中return true}else{return false}})
console.log(result) // [4, 5]// 简化写法
let result2 = [...new Set(arr)].filter(item => new Set(arr2).has(item))
console.log(result2)

求并集

let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
let arr2 = [4, 5, 6, 5, 6]// 求并集:连接两个数组 => 转为元素不重复的集合 => 转为数组
let union = [...new Set([...arr, ...arr2])]
console.log(union)
// [1, 2, 3, 4, 5, 6]

求差集

let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
let arr2 = [4, 5, 6, 5, 6]// 求差集-arr对arr2求差集,即求arr里面有但是arr2里没有的元素,相当于求交集的逆运算
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)))
console.log(diff) // [1, 2, 3]

14.Map

ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现了iterator接口,所以可以使用「扩展运算符」和for...of进行遍历
Map的属性和方法:

size,返回Map的元素个数
set,增加一个新元素,返回当前Map
get,返回键名对象的键值
has,检测Map中是否包含某个元素,返回Boolean
clear,清空集合,返回undefined

// 声明Map
let m = new Map()// 添加元素
m.set('name','LiMing') // 键名,键值
m.set('tell',function(){console.log('I am LiMing ')
})
let friend = {school: '三中'
}
m.set(friend,['小吴','小王','小芳'])// 删除元素
m.delete('tell')// 获取元素
let friends = m.get(friend)
console.log(friends)// 获取元素个数
let size = m.size
console.log(size)// 遍历Map
for(let item of m){console.log('item---',item)// 每一个item都是一个数组,第一个元素为键,第二个元素为值
}// 清空Map
m.clear()
console.log(m)
console.log(typeof m)

相关内容

热门资讯

幼儿园大班新年联欢会主持词   主持人:左XX  开场:  左:亲爱的老师、同学们:  合:大家好!  彭:20XX年马上就要过...
新春的主持稿 新春的主持稿  在日常生活和工作中,需要使用主持稿的情况越来越多,主持稿是主持人在会议或是节目当中串...
五四青年节的致辞 五四青年节的致辞(通用20篇)  在平日的学习、工作和生活里,大家总少不了要接触或使用致辞吧,致辞是...
新年年会简短优秀致辞 新年年会简短优秀致辞(通用8篇)  在生活、工作和学习中,大家都不可避免地会接触到致辞吧,致辞具有很...
告别仪式的主持词 告别仪式的主持词3篇  告别主持词篇一:  男:离别,是一个沉重的动词。  女:离别,一个让人一生难...
喜爱夜蒲2经典台词 喜爱夜蒲2经典台词  1、做要做到最好,玩要玩到最尽。  2、我们明知不能相爱,可还是相爱了,未曾绽...
领导年会致辞 领导年会致辞  无论在学习、工作或是生活中,大家对致辞都不陌生吧,致辞是指在举行会议或某种仪式时具有...
关于保险公司年会主持词 关于保险公司年会主持词  公司的类型有哪些  根据《中华人民共和国公司法》公司的主要形式为无限责任公...
在年会上的致辞 在年会上的致辞范文(精选5篇)  在平时的学习、工作或生活中,大家都写过致辞吧,致辞是指在举行会议或...
企业开工仪式致辞 企业开工仪式致辞(精选7篇)  在平时的学习、工作或生活中,大家都不可避免地会接触到致辞吧,致辞是指...
小学第二学期的开学典礼主持词 小学第二学期的开学典礼主持词  主持词已成为各种演出活动和集会中不可或缺的一部分。在当今中国社会,各...
升学宴主持词 升学宴主持词3篇  高考过后考生及家长需要考虑举办升学宴会酒席的事宜了,升学宴主持词怎么写?下面是小...
同学聚会致辞 同学聚会致辞(精选6篇)  在生活、工作和学习中,大家都尝试过写致辞吧,在各种重大的庆典、外交、纪念...
升学宴会主持词 升学宴会主持词9篇  主持人在台上表演的灵魂就表现在主持词中。在当今社会中,各种场合中活跃现场气氛的...
早会主持词 早会主持词范文4篇  早会能对一天或是一周亦或是一个月的工作作出及时的总结和临时性的调整,在工作中有...
服装展示主持词示例 服装展示主持词示例  篇一:服装展示串词  龙 蓓  1、现在出场的是宾馆总台接待,为大家作展示的是...
重阳节主持词 重阳节主持词(精选13篇)  主持词分为会议主持词、晚会主持词、活动主持词、婚庆主持词等。在人们越来...
商场活动主持词   商场活动主持词  亲爱的顾客朋友:  大家下午好!  “金猪报捷去,玉鼠送春来”。欢迎大家在这个...
主婚人简短婚礼致辞 主婚人简短婚礼致辞  结婚是件大事,那么主婚人如何向新人们致辞呢?怎么做致辞才简短又大气呢?下面我们...