目录
1.let & const
1) let,作用与var类似,用于声明变量
特性:
let
不能重复声明变量,var
可以重复声明变量;- 块级作用域,
es5
中存在全局作用域、函数作用域、eval
作用域;es6
中引入了块级作用域,let
声明的变量在块级作用域{}
内有效 let
声明的变量不存在var
的变量提升问题
举个例子:
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><divclass="container"><h2class="page-header">点击切换颜色</h2><divclass="item">1</div><hr><divclass="item">2</div><hr><divclass="item">3</div></div><script>// 获取div对象let items = document.getElementsByClassName('item')// 遍历并绑定事件 遍历时let ifor(let i =0; i < items.length; i++){
items[i].onclick=function(){
items[i].style.background ='pink'}}/*
相当于在3个块级作用域内分别声明了i
{
let i = 0
items[i].onclick = function(){
items[i].style.background = 'pink'
}
}
{
let i = 1
items[i].onclick = function(){
items[i].style.background = 'pink'
}
}
{
let i = 2
items[i].onclick = function(){
items[i].style.background = 'pink'
}
}
*//*
// 遍历并绑定事件 遍历时var i
for(var i = 0; i < items.length; i++){
items[i].onclick = function(){
// 修改当前元素的背景颜色
this.style.background = 'pink' // 此处this指向’被绑定的元素对象‘,即调用该函数的对象
// 此处不能和上文一样使用 items[i].style.background = 'pink',
// 因为var的i不考虑块级作用域, 则相当于在全局声明了一个变量,循环结束后i=3,
// 函数执行时向上层寻找最终得到全局变量i=3,而items[3]为undefined
}
}
相当于
{
var i = 0
// ...
}
{
var i = 1
// ...
}
{
var i = 2
// ...
}
{
var i = 3
}
*/</script></body><style>.item{width: 200px;height: 50px;border-radius: 2%;background-color: brown;}</style></html>
2) const 用于声明常量
注意事项:
- 一定要赋初始值
- 一般常量使用大写(属于编程规范)
- 常量值不能修改
- 存在块级作用域
- 对于数组和对象的元素修改,不算做对常量的修改,不会报错(因为引用数据类型保存的是内存地址,所以声明数组和对象时可以使用
const
声明,以此保证其保存的内存地址不变)
2.解构赋值
ES6
允许按照一定模式从数组和对象中提取值,对变量进行赋值
1) 数组的解构
const Web =['html','css','javascript']let[tool1, tool2, tool3]= Web
console.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}= liMing
console.log(name)// 'liMing'
console.log(age)// '22'
console.log(tell)// f(){...}tell()// I am liMing
3.模板字符串
特性:
- (反引号)内容中可以直接出现换行符,’ '和" "中则不可以,出现会报错
- 可以直接进行变量拼接
4.简化对象写法
ES6
允许在大括号里面,直接写入变量和函数,作为对象的属性和方法(在属性名和变量名相同的情况下),这样的书写更加简洁
let name ='LiMing'lettell=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
指向调用其函数的对象
functiongetName(){
console.log(this.name)}letgetName2=()=>{
console.log(this.name)}// 设置window对象的name属性
window.student ='LiMing'const student ={name:'HanMei'}// 直接调用getName()// LiMinggetName2()// LiMing// call方法调用getName.call(student)// HanMeigetName2.call(student)// LiMing
2.箭头函数不能作为构造函数实例化对象
letPerson=(name, age)=>{this.name = name
this.age = age
}let me =newPerson('LiMing',20)// 报错:Uncaught TypeError: Person is not a constructor
**3.箭头函数不能使用
arguments
变量,但是可以使用.
...rest
**
letfn=()=>{
console.log(arguments)}fn(1,2,3)// 报错:Uncaught ReferenceError: arguments is not definedletfn2=(...rest)=>{
console.log(...rest)}fn2('a','b','c')// a b c
4.箭头函数的简写
① 当形参有且只有一个的时候,可以省略
()
② 当代码体只有一条语句的时候,可以省略
{}
,此时
return
必须省略,而且语句的执行结果就是函数的返回值
// 当形参有且只有一个的时候,可以省略`()`letadd=n=>{return n + n
}
console.log(add(9))// 当代码体只有一条语句的时候,可以省略`{}`,此时`return`必须省略,而且语句的执行结果就是函数的返回值letpow=n=> n*n
console.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){returntrue}else{returnfalse}})// 可以用箭头函数// 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
允许给函数参数赋初始值
functionadd(a, b, c=10){// 具有默认值的参数,一般位置要靠后return a + b + c
}
console.log(add(1,2,))
可以与解构赋值一起使用
functionconnect({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获取实参的方式functionprintStudent(){
console.log(arguments)// arguments为一个对象}printStudent('LiMing','HanMeimei')// ES6获取实参的方式functionprintFriend(friend1, friend2,...rest){// rest参数必须放在形参列表最后,否则会报错
console.log(friend1)
console.log(friend2)
console.log(rest)// 得到一个数组,可以使用数组api}printFriend('小猫','小狗','兔子','鸭子')// 小猫// 小狗// ['兔子','鸭子']
8.扩展运算符
...
能将「数组」转为逗号分隔的「参数序列」
*注:虽然形式与
rest
参数类似,但是
rest
参数是用在函数定义时的形参位置,扩展运算符是用在函数实际调用时的实参位置*
constSTUDENTS=['小明','小芳','小红']functionprintStudent(){
console.log(arguments)}printStudent(STUDENTS)// 参数为一个数组,数组内包含3个元素printStudent(...STUDENTS)// 参数为3个元素
应用场景:
- 数组的合并
constSTUDENTS1=['小明','小芳','小红']constSTUDENTS2=['小吴','小王']// es5写法constSTUDENTS_ES5=STUDENTS1.concat(STUDENTS2)// es6写法constSTUDENTS_ES6=[...STUDENTS1,...STUDENTS2]
console.log('es5------',STUDENTS_ES5)
console.log('es6------',STUDENTS_ES6)
- 数组的克隆
constSTUDENTS1=['小明','小芳','小红']constPUPIL=[...STUDENTS1]// 注意:如果数组内元素是引用类型,拷贝的是内存地址,为浅拷贝
console.log('PUPIL----',PUPIL)
- 将伪数组转为真正的数组
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特点
Symbol
的值是唯一的,用来解决命名冲突的问题Symbol
值不能与其他数据进行运算,也不能与自己进行运算,譬如+、-、*、/、比较运算Symbol
定义的对象属性不能使用for…in
遍历,但是可以使用Reflect.ownKeys
来获取对象的所有键名
创建Symbol
- 通过
let s2 = Symbol('张三')
的方式创建Symbol
,'张三’作为Symbol
描述,作用相当于注释,这种方式创建的Symbol
,即使传入的描述一致,但实际返回的值是不同的
// 创建Symbollet s =Symbol()
console.log(s,typeof s)// Symbol() "symbol"let s2 =Symbol('张三')// '张三'作为Symbol描述,作用相当于注释let s3 =Symbol('张三')// 即使传入的描述一致,但实际返回的值是不同的
console.log(s2 === s3)// false
- 通过
Symbol.for()
创建Symbol
,这种方式创建Symbol
,传入的描述一致,实际返回的值也一致,可以得到唯一的Symbol
值
// Symbol.for创建Symbollet 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
值,指向语言内部使用的方法,比如
Symbol.hasInstance
当其他对象使用instanceof
运算符,判断是否为该对象的实例时,会调用这个方法
classPerson{static[Symbol.hasInstance](param){
console.log('param----', param)
console.log('检测类型')}}let o ={}
console.log(o instanceofPerson)// param---- {}// 检测类型// false
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]]
Symbol.unscopables
该对象指定了使用with
关键字时,哪些属性会被with
环境排除Symbol.match
当执行str.match(myObject)
时,如果该属性存在,会调用它,返回该方法的返回值Symbol.replace
当该对象被str.replace(myObject)
方法调用时,会返回该方法的返回值Symbol.search
当该对象被str.search(myObject)
方法调用时,会返回该方法的返回值Symbol.split
当该对象被str.split(myObject)
方法调用时,会返回该方法的返回值Symbol.iterator
对象进行for ... of
循环时,会调用Symbol.iterator
方法,返回该对象的默认遍历器Symbol.toPrimitive
该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值Symbol.toStringTag
在该对象上调用toString
方法时,返回该方法的返回值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
工作原理:
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的
next
方法,指针自动指向数据结构的第一个成员 - 接下来不断调用
next
方法,指针一直往后移动,直到指向最后一个成员 - 每调用
next
方法返回一个包含value
和done
属性的对象,***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
遍历函数执行后返回的迭代器对象,每一次遍历的item
为yield
后的表达式或者自变量的值
function*gen1(){yield'耳朵'// 函数代码的分隔符yield'尾巴'}// 遍历,每一次遍历的item为yield后的表达式或者自变量的值for(let item ofgen1()){
console.log(item)}// 执行结果:// 耳朵// 尾巴// 注:next调用和for...of调用同时存在,只会支持最先的一个
- 生成器函数的参数传递
function*gen(args){
console.log(args)// 'aaa'let one =yield111
console.log(one)// 'bbb'let two =yield222
console.log(two)// 'ccc'let three =yield333
console.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// 用生成器函数实现functionone(){setTimeout(()=>{
console.log(111)
iterator.next()},1000)}functiontwo(){setTimeout(()=>{
console.log(222)
iterator.next()},2000)}functionthree(){setTimeout(()=>{
console.log(333)},3000)}function*gen(){yieldone()yieldtwo()yieldthree()}let iterator =gen()
iterator.next()// 以下为回调地域做法// setTimeout(()=>{// console.log(111)// setTimeout(()=>{// console.log(222)// setTimeout(()=>{// console.log(333)// }, 3000)// }, 2000)// }, 1000)
- 生成器函数实例2: 模拟获取 用户数据 --> 订单数据 --> 商品数据
// 模拟获取 用户数据 --> 订单数据 --> 商品数据functiongetUsers(){setTimeout(()=>{let data ='用户数据'
iterator.next(data)// 相当于把得到的数据,传回users},1000)}functiongetOrders(){setTimeout(()=>{let data ='订单数据'
iterator.next(data)},2000)}functiongetGoods(){setTimeout(()=>{let data ='商品数据'
iterator.next(data)},3000)}// 定义生成器函数function*gen(){let users =yieldgetUsers()
console.log(users)// 用户数据let orders =yieldgetOrders()
console.log(orders)// 订单数据let goods =yieldgetGoods()
console.log(goods)// 商品数据}// 调用生成器函数,获取迭代器对象let iterator =gen()
iterator.next()
12.Promise
Promise
是
ES6
引入的异步编程的新解决方案。语法上
Promise
是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果
Promise
构造函数:Promise(excutor){}
Promise.prototype.then
方法Promise.prototype.catch
方法
基本使用
// 实例化Promise对象const p =newPromise(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 =newPromise(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 =newPromise((resolve, reject)=>{const xhr =newXMLHttpRequest()
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 =newPromise((resolve, reject)=>{setTimeout(()=>{resolve('用户数据')// reject('出错啦')},1000)})const result = p.then((value)=>{// p执行resolve后,状态为成功,执行第一个函数
console.log(value )// 1.返回非promise对象的情况// return 233 // 233// 2.返回promise对象returnnewPromise((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 =newPromise((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 => 读取文件3const p =newPromise((resolve, reject)=>{
fs.readFile('./resource/file1.md',(err,data)=>{resolve(data)})})
p.then((value)=>{returnnewPromise((resolve, reject)=>{
fs.readFile('./resource/file2.md',(err,data)=>{let data_all ={data1: value.toString(),data2: data.toString()}resolve(data_all)})})}).then((value)=>{returnnewPromise((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 =newPromise((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 =newSet(['风声','雨声','读书声','风声'])// 可以接受可迭代数据,一般传入数组// '风声','雨声','读书声'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 =[...newSet(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 =[...newSet(arr)].filter(item=>{// 对arr去重并进行遍历let s2 =newSet(arr2)// 将arr2变为元素不重复的集合if(s2.has(item)){// 如果元素存在s2中returntrue}else{returnfalse}})
console.log(result)// [4, 5]// 简化写法let result2 =[...newSet(arr)].filter(item=>newSet(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 =[...newSet([...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 =[...newSet(arr)].filter(item=>!(newSet(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
// 声明Maplet m =newMap()// 添加元素
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)// 遍历Mapfor(let item of m){
console.log('item---',item)// 每一个item都是一个数组,第一个元素为键,第二个元素为值}// 清空Map
m.clear()
console.log(m)
console.log(typeof m)
版权归原作者 英俊先生 所有, 如有侵权,请联系我们删除。