ES5-ES12知识点摘要

对ECMAScript发展历程一些新增知识点摘要。

ES5新增

  1. 严格模式
// 1: 不能使用未声明的变量
'use strict';
a = 1  // Uncaught ReferenceError: a is not defined

// 2:不能删除变量、对象、函数
'use strict';
let a = 1
delete a // Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.

// 3:禁止this关键字指向全局对象指向undefined
1
2
3
4
5
6
7
8
9
10
  1. 数组

Array.isArray

判断是不是数组, 返回boolean值

const arr = [1, 2]
Array.isArray(arr) // true
1
2

迭代方法

const arr = [1, 2, 3]
// 返回值:boolean,有一个为真,则为真
arr.some(item => item === 1) // true
// 返回值:boolean,全为真则为真
arr.every(item => item === 1) // false
// 返回值:undefined, 遍历循环每一项
arr.forEach(item => console.log(item)) // 1, 2, 3
// 返回值:新数组,遍历循环每一项
arr.map(item => item + 1) // [2, 3, 4]
// 返回值:新数组,遍历循环每一项 过滤
arr.filter(item => item % 2) // [1, 3]
// 返回值:自定义,遍历循环每一项
arr.reduce((pre, cur) => {
  // pre 前一项值,刚开始如果没有定义第二个参数 则取数组第一项
  return pre + cur
}, 0) // 6
// 和上面类似 从右往左遍历
arr.rightReduce()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  1. JSON
const arr = [1, 2]

JSON.stringify(arr)

JSON.parse(JSON.stringify(arr))
1
2
3
4
5

ES6新增

  1. 箭头函数

箭头函数没有this,都是自动绑定父作用域this指向,无法通过call, apply, bind 修改this指向

详情见this

const fn = () => {
  // 此时无法判断this指向 this指向只有调用的时候才知道
  console.log(this)
}

fn() // window
fn.call({a: 1}) // window

1
2
3
4
5
6
7
8

es6新增class,关于构造函数详细类容见构造函数

class Person {
  constructor(name) {
    this.name = name
  }
  play() {
    console.log(this.name)
  }
  // 调用方式 Person.say()
  static say() {
    console.log('静态方法')
  }
}

// 继承 关键字 `extends` `super`
class Student extends Person {
  constructor(name, age) {
    super(name) // 一定要在最前面调用
    this.age = age
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  1. 对象属性方法简写
const a = 1
const obj = {
  a,
  fn() {
    console.log('方法简写')
  }
}
1
2
3
4
5
6
7
  1. 模板字符串
const temp = '模板'
const str = `这是个${temp}字符串`  // 这是个模板字符串
1
2
  1. 数组解构和扩展运算符
const arr = [1, 2, 3, 4]
const [a, ...rest] = arr  // a: 1 rest: [2, 3, 4]
// 交换数组值
const arr1 = [1, 2];
[arr1[1], arr1[0]] = [arr1[0], arr1[1]]
1
2
3
4
5
  1. let|const

详见作用域与闭包

与var的区别

  1. 无变量提升

  2. 块级作用域

  3. 暂时性死区

  4. 必须先声明后使用

  1. 迭代器 for of
// 对于可迭代的数据类型使用
const arr = [1, 2, 3]

for (const item of arr) {
  console.log(item) // 1, 2, 3
}
for (const item of arr.values()) {
  console.log(item) // 1, 2, 3
}
for (const item of arr.keys()) {
  console.log(item) // 0, 1, 2
}
for (const item of arr.entries()) {
  console.log(item) // [0, 1], [1, 2], [2, 3]
}

// 支持异步
for await (const item of arr) {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  1. 模块化
// 在nodejs中采用 commonjs  js中采用 AMD、CMD方案

// commonjs
module.exports = {}
exports.a = 1

const a = require('../路径')

// es module
export const a = 1
export default {a: 1}

import a from '../路径'

// 俩者区别
/**
  CommonJs
    可以动态加载语句,代码发生在运行时
    CommonJs混合导出,还是一种语法,只不过不用声明前面对象而已,当我导出引用对象时之前的导出就被覆盖了
    CommonJs导出值是拷贝,可以修改导出的值,这在代码出错时,不好排查引起变量污染
  Es Module
    Es Module是静态的,不可以动态加载语句,只能声明在该文件的最顶部,代码发生在编译时
    Es Module混合导出,单个导出,默认导出,完全互不影响
    Es Module导出是引用值之前都存在映射关系,并且值都是可读的,不能修改
 * /
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

注意

Es Module在后续ES11支持了动态导入 import('../路径')返回一个promise对象

  1. Map/WeakMap, Set/WeakSet
// 新增数据类型 值唯一
// Map/WeakMap 字典  WeakMap区别在于 key只能是引用类型
// 具备可迭代的所有方法 map.entries() map.values()
const map = new Map([[1, 2], [2, 3]])
const weakMap = new WeakMap([[{}, 2]])
map.set(3, 4) // Map(3) {1 => 2, 2 => 3, 3 => 4}
map.get(1) // 2
map.delete(1) // true
map.has(1) // false
map.size // 2
map.clear()


// Set/WeakSet 集合  WeakSet区别在于 成员只能是引用类型
const set = new Set([1, 2, 3])
const weakSet = new WeakSet([{}, {a: 1}])
set.add(3) // 会自动去重 // Set(3) {1, 2, 3}
set.delete(1) // true
set.has(1) // false
set.size // 2
set.clear()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  1. Symbol
// Symbol新增类型 表示独一无二
const symbol1 = Symbol(1)
const symbol2 = Symbol(1)

symbol1 === symbol2 // false
// 实际应用 定义 即导出 只采用一个地方的定义 比如
const obj = {
  [symbol1]: 2222
}
console.log(obj[symbol1]) // 2222
1
2
3
4
5
6
7
8
9
10
  1. Proxy
const data = {a: 1, b: 2}

const handler = {
   get(target, key, recevier) {
       return Reflect.get(target, key, recevier)
   },
  set(target, key, value, recevier) {
     return Reflect.set(target, key, value, recevier)
   },
   deleteProperty(target, key) {
     return Reflect.deleteProperty(target, key)
  }
}

const proxyData = new Proxy(data, handler)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

ES7新增

  1. Array.includes
const arr = [1, 2, 3]

arr.includes(1) // true
arr.includes(4) // false
1
2
3
4
  1. 指数
console.log(2 ** 3) // 8
console.log(Math.pow(2, 3)) // 8
1
2

ES8新增

  1. Object.keys, Object.values, Object.entries
const obj = {
  a: 1,
  b: 2
}

console.log(Object.keys(obj)) // ['a', 'b']
console.log(Object.values(obj)) // [1, 2]
console.log(Object.entries(obj)) // [['a', 1], ['b', 2]]
1
2
3
4
5
6
7
8
  1. padEnd, padStart
// 向前或向后用0补5位
const str = '111'
console.log(str.padEnd(5, 0)) // 11100
console.log(str.padStart(5, 0)) // 00111
1
2
3
4
  1. async await

是generator语法糖

ES9新增

  1. Promise.prototype.finally(() => {})

Promise对象方法 不管Promise 状态是REJECTED还是FULFILLED 都会执行finally

ES10新增

  1. 数组扁平化
const arr = [1, 2, 3, [2, 3]]

// 扁平化一层
console.log(arr.flat()) // [1, 2, 3, 2, 3]
// 最大化扁平
console.log(arr.flat(Number.MAX_SAFE_INTEGER))
// 遍历
arr.flatMap(item => {
  console.log(item)
  return item
})
// 缺点 子项类型会改变
arr.toString().split(',')
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. Object.fromEntries
// 将entries或二维数组转对象
const arr = [[1, 2], ['a', 'cc']]
console.log(Object.fromEntries(arr)) // {1: 2, a: 'cc'}
1
2
3
  1. trimStart, trimEnd
const str = ' abc '
console.log(str.trim()) // 'abc' 去除左右空格
console.log(str.trimStart()) // 'abc ' 去除左空格
console.log(str.trimEnd()) // ' abc'  去除右空格
1
2
3
4

ES11新增

  1. 动态import
const promise = import('....') // 返回promise
// 路由懒加载就是如此
1
2
  1. Promise.allSettled
const promiseArr = []

const results = await Promise.allSettled(promiseArr)
// 不管失败还是成功都会返回出来 自己过滤处理
results.filter(item => item.status === 'REJECTED') // 失败的promise
results.filter(item => item.status === 'FULFILLED') // 成功的promise

// 而 Promise.all() Promise.race()

// Promise.all 只要有一个错误 就会进入catch
// Promise.race 赛道 , 返回最先完成的那个
1
2
3
4
5
6
7
8
9
10
11
  1. 空位合并操作
const a = ''
// 只有当a为null或void 0时, 取后面值
console.log(a ?? 1) // ''
const b = ''
// 当b 为 falsely 变量时 取后面值
console.log(b || 1) // 1
1
2
3
4
5
6
  1. 可选链操作符
const obj = {a: 1, b: {a: 2}}

console.log(obj.b?.a) // 2 当obj中有b时才会取a 否则输出void 0
console.log(obj.c?.a) // void 0
1
2
3
4

ES12新增

  1. replaceAll
const str = '1aabbccb'
console.log(str.replaceAll('a', 'b')) // '1bbbbccb'
console.log(str.replace(/a/g, 'b')) // '1bbbbccb'
1
2
3
  1. 数字分隔符
const num = 123_123_444
console.log(num) // 123123444
1
2
  1. 逻辑赋值运算符
let a = 1
a ||= 2 // 当a为falsely 变量时 赋值为2

a &&= 2 // 当a为truthy 变量时 赋值为2

a ??= 2 // 当a为void 0 或者null 时 赋值为2
1
2
3
4
5
6
上次更新: 2021/10/20 下午4:40:42
贡献者: 陈书进