您现在的位置是:首页 >学无止境 >ES6至ES12网站首页学无止境

ES6至ES12

CrazyxxLu 2024-08-27 00:01:02
简介ES6至ES12

ES6至ES12

原文地址:https://mp.weixin.qq.com/s/knmV9Y6FkC33dtaM9R3Rqg

ES6

1、let 和 const

2、默认参数

开发中你曾遇到过这样的问题,如果参数不传进来,你就设置默认参数

function fn (name, age) {
  var name = name || 'jack'
  var age = age || 18
  console.log(name, age)
}
fn() // 林三心 18

块级作用域解决问题:

function fn (name = 'jack', age = 18) {
  console.log(name, age)
}
fn() // jack 18
fn('sunshine', 22) // sunshine 22

3、扩展运算符

曾经想要拼接多个数组只能这么做

const arr1 = [1, 2, 4]
const arr2 = [4, 5, 7]
const arr3 = [7, 8, 9]

const arr = arr1.concat(arr2).concat(arr3)
[
  1, 2, 4, 4, 5,
  7, 7, 8, 9
]

现在

const arr1 = [1, 2, 4]
const arr2 = [4, 5, 7]
const arr3 = [7, 8, 9]

const arr = [...arr1, ...arr2, ...arr3]
[
  1, 2, 4, 4, 5,
  7, 7, 8, 9
]

4、剩余参数

function fn (name, ...params) {
  console.log(name)
  console.log(params)
}
fn ('林三心', 1, 2) // 林三心 [ 1, 2 ]
fn ('林三心', 1, 2, 3, 4, 5) // 林三心 [ 1, 2, 3, 4, 5 ]

5、模板字符串

const name = '林三心'
const age = '22'

console.log(`${name}今年${age}岁啦`) // 林三心今年22岁啦

6、Object.keys

可以用来获取对象的key的集合,进而可以获得对应key的value

const obj = {
  name: 'jack',
  age: 22,
  gender: '男'
}

const keys = Object.keys(obj)
console.log(keys) // [ 'name', 'age', 'gender' ]

7、箭头函数

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、箭头函数没有原型对象
  • 5、箭头函数不能改变this指向

8、Array.prototype.forEach

ES6新加的数组遍历方法

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 ]

9、Array.prototype.map

常用于返回一个处理过后的新数组

const mapArr = [1, 2, 3, 4, 5]

// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,对每一个元素进行翻倍
const mapArr2 = mapArr.map((num, index, arr) => 2 * num)
console.log(mapArr2)
[ 2, 4, 6, 8, 10 ]

10、Array.prototype.filter

11、Array.prototype.some

some,意思就是只要有一个是真,那就返回真

const someArr = [false, true, false, true, false]

// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,只要有一个为true,就返回true,一个都true都没有,就返回false
const someArr2 = someArr.some((bol, index, arr) => bol)
console.log(someArr2)
true

12、Array.prototype.every

every跟some是相反的,some是只要有一个就行,every是要所有为真才返回真

13、Array.prototype.reduce

// 计算 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

14、对象属性同名简写

const name = 'jack'
const age = '22'

// 属性同名可简写
const obj = {
  name,
  age
}

console.log(obj) // { name: 'jack', age: '22' }

15、Promise

16、class

17、解构赋值

const obj = {
  name: 'jack',
  age: 22,
  gender: '男'
}

const { name, age, gender } = obj

也可以进行数组的解构

const arr = [1, 2, 3]

const [a, b, c] = arr
console.log(a, b, c) // 1 2 3

18、find 和 findIndex

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined

  • find:找到返回被找元素,找不到返回undefined
  • findIndex:找到返回被找元素索引,找不到返回-1

19、for of 和 for in

for ... in是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()for ... of

20、Set 和 Map

Set有点类似于Array数组*,但是和数组的区别是Set的元素不能重复*

set()常用功能就是数组去重

const arr = [1, 2, 3, 4, 4, 5, 5, 66, 9, 1]

// Set可利用扩展运算符转为数组哦
const quchongArr = [...new Set(arr)]
console.log(quchongArr) // [1,  2, 3, 4, 5, 66, 9]

Map Map对比object最大的好处就是,key不受类型限制

一个 Object 的键必须是一个 String 或是 Symbol

// 定义map
const map1 = new Map()
// 新增键值对 使用 set(key, value)
map1.set(true, 1)
map1.set(1, 2)
map1.set('哈哈', '嘻嘻嘻')
console.log(map1) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }
// 判断map是否含有某个key 使用 has(key)
console.log(map1.has('哈哈')) // true
// 获取map中某个key对应的value 使用 get(key)
console.log(map1.get(true)) // 2
// 删除map中某个键值对 使用 delete(key)
map1.delete('哈哈')
console.log(map1) // Map(2) { true => 1, 1 => 2 }

// 定义map,也可传入键值对数组集合
const map2 = new Map([[true, 1], [1, 2], ['哈哈', '嘻嘻嘻']])
console.log(map2) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }

Map 中的键是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。

Map 的键值对个数可以轻易地通过 size 属性获取。Object 的键值对个数只能手动计算。

Map可迭代的 的,所以可以直接被迭代。Object 没有实现 迭代协议,所以使用 JavaSctipt 的 for…of 表达式并不能直接迭代对象。

Map在频繁增删键值对的场景下表现更好。Object在频繁添加和删除键值对的场景下未作出优化。

ES7

1、includes

传入元素,如果数组中能找到此元素,则返回true,否则返回false

跟indexOf很像,但还是有区别的

const arr = [1, 2, NaN]

console.log(arr.indexOf(NaN)) // -1  indexOf找不到NaN
console.log(arr.includes(NaN)) // true includes能找到NaN

2、求幂运算符

以前求幂,我们需要这么写

const num = Math.pow(3, 2) // 9
const num = 3 ** 2 // 9

ES8

1、Object.values

const obj = {
  name: 'jack',
  age: 22,
  gender: '男'
}

const values = Object.values(obj)
console.log(values) // [ 'jack', 22, '男' ]

2、Object.entries

可以用来获取对象的键值对集合

const obj = {
  name: 'jack',
  age: 22,
  gender: '男'
}

const entries = Object.entries(obj)
console.log(entries) 
// [ [ 'name', 'jack' ], [ 'age', 22 ], [ 'gender', '男' ] ]

3、async/await

这个是很常用的语法了,我的理解就是:以同步方式执行异步操作

ES9

1、for await of

function fn (time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time}毫秒后我成功啦!!!`)
    }, time)
  })
}

async function asyncFn () {
  const arr = [fn(3000), fn(1000), fn(1000), fn(2000), fn(500)]
  for await (let x of arr) {
    console.log(x)
  }
}

asyncFn()
3000毫秒后我成功啦!!!
1000毫秒后我成功啦!!!
1000毫秒后我成功啦!!!
2000毫秒后我成功啦!!!
500毫秒后我成功啦!!!

2、Promise.finally

新增的Promise方法,无论失败或者成功状态,都会执行这个函数

ES10

1、Array.flat

有一个二维数组,我想让他变成一维数组:

const arr = [1, 2, 3, [4, 5, 6]]

console.log(arr.flat()) // [ 1, 2, 3, 4, 5, 6 ]

2、Array.flatMap

let arr = ["科比 詹姆斯 安东尼", "利拉德 罗斯 麦科勒姆"];

转化为

[ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]

第一时间想到map + flat

console.log(arr.map(x => x.split(" ")).flat());
// [ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]

flatMap就是flat + map,一个方法顶两个

console.log(arr.flatMap(x => x.split(" ")));
// [ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]

3、BigInt

BigInt是ES10新加的一种JavaScript数据类型,用来表示表示大于 2^53 - 1 的整数,2^53 - 1是ES10之前,JavaScript所能表示最大的数字

所以以后面试官问你JavaScript有多少种数据类型,别傻傻答6种了,要答8种,把ES6的Symbol和ES10的BigInt也加上去

4、Object.fromEntries

前面ES8的Object.entries是把对象转成键值对数组,而Object.fromEntries则相反,是把键值对数组转为对象

const arr = [
  ['name', 'jack'],
  ['age', 22],
  ['gender', '男']
]

console.log(Object.fromEntries(arr)) // { name: 'jack', age: 22, gender: '男' }

他还有一个用处,就是把Map转为对象

const map = new Map()
map.set('name', '林三心')
map.set('age', 22)
map.set('gender', '男')

console.log(map) // Map(3) { 'name' => '林三心', 'age' => 22, 'gender' => '男' }

const obj = Object.fromEntries(map)
console.log(obj) // { name: '林三心', age: 22, gender: '男' }

5、String.trimStart && String.trimEnd

咱们都知道JavaScript有个trim方法,可以清除字符串首尾的空格

const str = '    jack    '
console.log(str.trim()) // 'jack'

trimStart和trimEnd用来单独去除字符串的首和尾的空格

ES11

1、Promise.allSettled

ES11新增的Promise的方法

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
  • 把每一个Promise的结果,集合成数组,返回

ES12

1、Promise.any

E12新增的Promise的方法

  • 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
  • 如果有一个Promise成功,则返回这个成功结果
  • 如果所有Promise都失败,则报错

Symbol的使用

应用场景1:使用Symbol来作为对象属性名

平常我们对象的属性都是字符串

const obj = {
  name: 'jack',
  age: 23
}
console.log(obj['name']) // 'jack'
console.log(obj['age']) // 23

其实也可以用Symbol来当做属性名

const gender = Symbol('gender')
const obj = {
  name: 'jack',
  age: 23,
  [gender]: '男'
}
console.log(obj['name']) // 'jack'
console.log(obj['age']) // 23
console.log(obj[gender]) // 男

但是Symbol作为属性的属性不会被枚举出来,这也是JSON.stringfy(obj)时,Symbol属性会被排除在外的原因

其实想获取Symbol属性也不是没办法。

// 方法一
console.log(Object.getOwnPropertySymbols(obj)) // [ Symbol(gender) ]
// 方法二
console.log(Reflect.ownKeys(obj)) // [ 'name', 'age', Symbol(gender) ]

应用场景2:使用Symbol定义类的私有属性

以下例子,PASSWORD属性无法在实例里获取到

class Login {
  constructor(username, password) {
    const PASSWORD = Symbol()
    this.username = username
    this[PASSWORD] = password
  }
  checkPassword(pwd) { return this[PASSWORD] === pwd }
}

const login = new Login('123456', 'hahah')

console.log(login.PASSWORD) // 报错
console.log(login[PASSWORD]) // 报错
console.log(login[PASSWORD]) // 报错
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。