一、ES6 
1.let和const 
- var有变量提升,有初始化提升,值可变
- let有变量提升,没有初始化提升,值可变
- const有变量提升,没有初始化提升,值不可变,但如果是定义对象,则属性可变
javascript
// 块级作用域解决
for(var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i)
  })
} // 5 5 5 5 5
for(let i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i)
  })
} // 0 1 2 3 42.默认参数 
调用函数时,如果不提供参数,将使用默认参数(ES6)
javascript
function fn (name = 'zk', age = 18) {
  console.log(name, age)
}
fn() // zk 18
fn('sunshine', 22) // sunshine 223.扩展运算符 
凭借数组时不需要再借助concat
javascript
const arr1 = [1, 2, 4]
const arr2 = [4, 5, 7]
const arr3 = [7, 8, 9]
// const arr = arr1.concat(arr2).concat(arr3)
const arr = [...arr1, ...arr2, ...arr3]
[
  1, 2, 4, 4, 5,
  7, 7, 8, 9
]4.剩余参数 
一个函数,传递参数的个数不确定时,可以使用
javascript
function fn (name, ...params) {
  console.log(name)
  console.log(params)
}
fn ('zk', 1, 2) // zk [ 1, 2 ]
fn ('zk', 1, 2, 3, 4, 5) // zk [ 1, 2, 3, 4, 5 ]5.模板字符串 
以前拼接字符串
javascript
const name = 'zk'
const age = '22'
console.log(name + '今年' + age + '岁啦') // zk今年22岁啦现在拼接字符
javascript
const name = 'zk'
const age = '22'
console.log(`${name}今年${age}岁啦`) // 林三心今年22岁啦6.Object.keys 
可以用来获取对象的key的集合,进而拿到对应key的value
javascript
const obj = {
  name: 'zk',
  age: 22,
  gender: '男'
}
const keys = Object.keys(obj)
console.log(keys) // [ 'name', 'age', 'gender' ]7.箭头函数 
普通函数:
javascript
function fn () {}
const fn = function () {}箭头函数:
javascript
const fn = () => {}
// 如果只有一个参数,可以省略括号
const fn = name => {}
// 如果函数体里只有一句return
const fn = name => {
    return 2 * name
}
// 可简写为
const fn = name => 2 * name
// 如果返回的是对象
const fn = name => ({ name: name })普通函数和箭头函数的区别:
- 1、箭头函数不可作为构造函数,不能使用new
- 2、箭头函数没有自己的this
- 3、箭头函数没有arguments对象
- 4、箭头函数没有原型对象
8.对象属性同名简写 
以前同名属性需要这么写
javascript
const name = 'zk'
const age = '22'
const obj = {
  name: name,
  age: age
}
console.log(obj) // { name: 'zk', age: '22' }ES6新增语法,只需这么写
javascript
const name = 'zk'
const age = '22'
// 属性同名可简写
const obj = {
  name,
  age
}
console.log(obj) // { name: 'zk', age: '22' }9.Promise 
成功状态:
javascript
function requestData () {
  // 模拟请求
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('zk')
    }, 1000)
  })
}
requestData().then(res => {
  console.log(res) // 一秒钟后输出 'zk'
}, err => {
  console.log(err)
})失败状态:
javascript
function requestData () {
  // 模拟请求
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('错误啦')
    }, 1000)
  })
}
requestData().then(res => {
  console.log(res)
}, err => {
  console.log(err) // 一秒钟后输出 '错误啦'
})all方法:
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 如果所有Promise都成功,则返回成功结果数组
- 如果有一个Promise失败,则返回这个失败结果
javascript
// 如果全都为成功
function fn(time) {
  return new Promise((resolve, reject) => {
    console.log(88)
    setTimeout(() => {
      resolve(`${time}毫秒后我成功啦!!!`)
    }, time)
  })
}
Promise.all([fn(2000), fn(3000), fn(1000)]).then(res => {
  // 3秒后输出 [ '2000毫秒后我成功啦!!!', '3000毫秒后我成功啦!!!', '1000毫秒后我成功啦!!!' ]
  console.log(res) 
}, err => {
  console.log(err)
})
// 如果有一个失败
function fn(time, isResolve) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      isResolve ? resolve(`${time}毫秒后我成功啦!!!`) : reject(`${time}毫秒后我失败啦!!!`)
    }, time)
  })
}
Promise.all([fn(2000, true), fn(3000), fn(1000, true)]).then(res => {
  console.log(res)
}, err => {
  console.log(err) // 3秒后输出 '3000毫秒后我失败啦!!!'
})race方法:
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 哪个Promise最快得到结果,就返回那个结果,无论成功失败
javascript
function fn(time, isResolve) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      isResolve ? resolve(`${time}毫秒后我成功啦!!!`) : reject(`${time}毫秒后我失败啦!!!`)
    }, time)
  })
}
Promise.race([fn(2000, true), fn(3000), fn(1000)]).then(res => {
  console.log(res)
}, err => {
  console.log(err) // 1秒后输出
})10.解构赋值 
以前想提取对象里的属性需要这么做:
javascript
const obj = {
  name: 'zk',
  age: 22,
  gender: '男'
}
const name = obj.name
const age = obj.age
const gender = obj.gender
console.log(name, age, gender) // zk 22 男ES6新增了解构赋值的语法:
javascript
const obj = {
  name: 'zk',
  age: 22,
  gender: '男',
  doing: {
    morning: '摸鱼',
    afternoon: '摸鱼',
    evening: 'sleep'
  }
}
const { name, age, gender } = obj
console.log(name, age, gender) // zk 22 男
// 解构重名
const { name: myname } = obj
console.log(myname) // zk
// 嵌套解构
const { doing: { evening } } = obj
console.log(evening) // sleep11.find和findIndex 
- find:找到返回被找元素,找不到返回undefined
- findIndex:找到返回被找元素索引,找不到返回-1
javascript
const findArr = [
  { name: '科比', no: '24' },
  { name: '罗斯', no: '1' },
  { name: '利拉德', no: '0' }
]
const kobe = findArr.find(({ name }) => name === '科比')
const kobeIndex = findArr.findIndex(({ name }) => name === '科比')
console.log(kobe) // { name: '科比', no: '24' }
console.log(kobeIndex) // 012.for of和for in 
- for in :遍历方法,可遍历对象和数组
- for of :遍历方法,只能遍历数组,不能遍历非iterable对象
javascript
const obj = { name: 'zk', age: 22, gender: '男' }
const arr = [1, 2, 3, 4, 5]
for(let key in obj) {
  console.log(key)
}
name
age
gender
for(let index in arr) {
  console.log(index)
}
0 1 2 3 4
for(let item of arr) {
  console.log(item)
}
1 2 3 4 513.Set和Map 
- Set
Set的基本用法:
javascript
// 可不传数组
const set1 = new Set()
set1.add(1)
set1.add(2)
console.log(set1) // Set(2) { 1, 2 }
// 也可传数组
const set2 = new Set([1, 2, 3])
// 增加元素 使用 add
set2.add(4)
set2.add('zk')
console.log(set2) // Set(5) { 1, 2, 3, 4, 'zk' }
// 是否含有某个元素 使用 has
console.log(set2.has(2)) // true
// 查看长度 使用 size
console.log(set2.size) // 5
// 删除元素 使用 delete
set2.delete(2)
console.log(set2) // Set(4) { 1, 3, 4, '林三心' }Set的不重复性:
javascript
// 增加一个已有元素,则增加无效,会被自动去重
const set1 = new Set([1])
set1.add(1)
console.log(set1) // Set(1) { 1 }
// 传入的数组中有重复项,会自动去重
const set2 = new Set([1, 2, 'zk', 3, 3, 'zk'])
console.log(set2) // Set(4) { 1, 2, 'zk', 3 }Set的不重复性中,要注意引用数据类型和NaN:
javascript
// 两个对象都是不用的指针,所以没法去重
const set1 = new Set([1, {name: 'zk'}, 2, {name: 'zk'}])
console.log(set1) // Set(4) { 1, { name: 'zk' }, 2, { name: 'z' } }
// 如果是两个对象是同一指针,则能去重
const obj = {name: 'zk'}
const set2 = new Set([1, obj, 2, obj])
console.log(set2) // Set(3) { 1, { name: 'zk' }, 2 }
咱们都知道 NaN !== NaN,NaN是自身不等于自身的,但是在Set中他还是会被去重
const set = new Set([1, NaN, 1, NaN])
console.log(set) // Set(2) { 1, NaN }14.Aaary.prototype.forEach 
ES6新加的数组遍历方法
javascript
const eachArr = [1, 2, 3, 4, 5]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数
eachArr.forEach((item, index, arr) => {
  console.log(item, index, arr)
})
1 0 [ 1, 2, 3, 4, 5 ]
2 1 [ 1, 2, 3, 4, 5 ]
3 2 [ 1, 2, 3, 4, 5 ]
4 3 [ 1, 2, 3, 4, 5 ]
5 4 [ 1, 2, 3, 4, 5 ]15.Array.prototype.map 
常用于返回一个处理过后的新数组
javascript
const mapArr = [1, 2, 3, 4, 5]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,对每一个元素进行翻倍
const mapArr2 = mapArr.map((num, index, arr) => 2 * num)
console.log(mapArr2)
[ 2, 4, 6, 8, 10 ]16.Array.prototype.filter 
用于过滤数组的方法
javascript
const filterArr = [1, 2, 3, 4, 5]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,返回大于3的集合
const filterArr2 = filterArr.filter((num, index, arr) => num > 3)
console.log(filterArr2)
[ 4, 5 ]17.Array.prototype.some 
只要有一个为true,就返回true
javascript
const someArr = [false, true, false, true, false]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,只要有一个为true,就返回true,一个都true都没有,就返回false
const someArr2 = someArr.some((bol, index, arr) => bol)
console.log(someArr2)
true18.Array.prototype.every 
every跟some是相反的,some是只有一个就行,every是要所有为真才返回真
javascript
const everyArr = [false, true, false, true, false]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,需要所有为true,才返回true,否则返回false
const everyArr2 = everyArr.every((bol, index, arr) => bol)
console.log(everyArr2)19.Array.prototype.reduce 
- 第一个参数callback函数: pre为上次return的值,next为数组的本次遍历的项
- 第二个参数为初始值,也是第一个pre
javascript
// 计算 1 + 2 + 3 + 4 + 5
const reduceArr = [1, 2, 3, 4, 5]
const sum = reduceArr.reduce((pre, next) => {
  return pre + next
}, 0)
console.log(sum) // 15
// 统计元素出现个数
const nameArr = ['zk', 'sunshine_z', 'zk', 'zk', '科比']
const totalObj = nameArr.reduce((pre, next) => {
  if (pre[next]) {
    pre[next]++
  } else {
    pre[next] = 1
  }
  return pre
}, {})
console.log(totalObj) // { 'zk': 3, sunshine_z: 1, '科比': 1 }