ES6中对对象字面量的写法进行了增强,主要包含以下三个方面的增强:
foo() {}的形式;[]包裹即可;const obj = { // 1.属性简写 name, age, // 2.方法简写 foo() { console.log('foo') }, // 3.计算属性名 [key]: 'value'}为了方便从数组或对象中获取数据,ES6给我们提供了解构的方案,可分为数组的解构和对象的解构。
数组的解构:注意数组的解构是按元素顺序来的。
const names = ['curry', 'kobe', 'klay', 'james']// 1.基本的解构,解构出数组所有的元素var [name1, name2, name3, name4] = namesconsole.log(name1, name2, name3, name4) // curry kobe klay james// 2.解构部分元素,只解构后面两个元素var [, , name3, name4] = namesconsole.log(name3, name4) // klay james// 3.解构出第一个元素,后面的元素放到一个新数组中var [name1, ...newNames] = namesconsole.log(newNames) // [ 'kobe', 'klay', 'james' ]// 4.解构数组的同时,给元素指定默认值,如果数组中没有该元素,就会使用默认值var [name1, name2, name3, name4, name5 = 'default'] = namesconsole.log(name1, name2, name3, name4, name5) // curry kobe klay james default对象的解构:对象的解构是不按顺序的,是根据key来赋值的。
const obj = { name: 'curry', age: 30, team: '金州勇士'}// 1.基本的解构var { name, age, team } = objconsole.log(name, age, team) // curry 30 金州勇士// 2.解构的同时重命名var { name: newName, age: newAge, team: newTeam } = objconsole.log(newName, newAge, newTeam) // curry 30 金州勇士// 3.解构的同时指定默认值,当对象中没有该属性时,就会取默认值var { height = '1.83' } = objconsole.log(height) // 1.83// 4.同时重命名和指定默认值var { height: newHeight = '1.83' } = objconsole.log(newHeight) // 1.83解构的应用场景:一般开发中拿到一个变量,可以对齐进行解构使用,比如对函数的参数进行解构。
function fn({ name, age, team }) { console.log(name, age, team)}fn(obj) // curry 30 金州勇士在ES5中,声明变量都是使用var,从ES6开始新增了两个声明变量的关键字let和const。
let关键字:从直观的角度来说,let和var是没有太大的区别的,都是用于声明一个变量。
let message = 'hello world'const关键字:const声明的变量称为常量,表示保存的数据一旦被赋值就不能再被修改了,但是如果是引用类型的数据,还是可以通过引用找到对应的对象进行修改的。
const obj = { name: 'curry', age: 30}const names = ['curry', 'kobe']obj.name = 'kobe'names.push('klay')console.log(obj) // { name: 'kobe', age: 30 }console.log(names) // [ 'curry', 'kobe', 'klay' ]// 注意:不能直接给引用类型重新赋值/* obj = {} // TypeError: Assignment to constant variable. names = [] // TypeError: Assignment to constant variable.*/注意:与var不同的是,let和const是不允许重复声明变量的。并且使用let和const声明的变量是具有自己的块级作用域的。var和let可以不设置初始值,const必须设置。
有关作用域提升的问题:
使用过var关键字的人都知道,var声明的变量是会进行作用域提升的,如果使用let和const声明的变量,是不允许在声明之前对其进行访问的,会直接报错。
console.log(message) // undefinedvar message = 'hello world'console.log(message) // ReferenceError: Cannot access 'message' before initializationlet message = 'hello world'为什么var声明的变量有作用域提升,而let和const没有呢?
总结:在上面的代码中,其实message在代码执行前就已经被创建了,在用let进行修饰后,js底层会对其进行约束,以至于在声明前不可以访问。
ES6允许使用字符串模板来嵌入JS的变量或者表达式来进行拼接。
使用``来编写字符串,可以${expression}来嵌入动态内容,里面可以写一个表达式。
const name = 'curry'const age = 30console.log(`My name is ${name}\nMy age is ${age}`)
标签模板字符串:模板字符串另外一种用法,可以用来调用函数,如果使用标签模板字符串,并且在调用的时候插入其他的变量。
${}的字符串组合;${}中传入的变量值;function fn(x, y, z) { console.log(x, y, z)}const name = 'curry'const age = 30fn`sojfo${name}hghaooa${age}jgoajg` // [ 'sojfo', 'hghaooa', 'jgoajg' ] curry 30应用:在react中编写css就有这么一个库叫styled-components,其原理就是使用的标签模块字符串。

在ES6之前,我们编写的函数参数是没有默认值的,而ES6给我们提供了默认参数,如果传入了该参数就使用传入的值,没有传入就使用默认值。
在ES6之前,如果想实现默认参数的效果,就必须编写以下最终代码。
function fn() { var m = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'aaa' var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'bbb' console.log(m, n)}fn() // aaa bbbfn(111, 222) // 111 222在ES6中,可以在声明函数时给其参数默认值。
一般默认值写法:
function fn(m = 'aaa', n = 'bbb') { console.log(m, n)}默认值搭配解构的使用:
// 1.写法一:对象参数+解构function fn1({ name, age } = { name: 'curry', age: 30 }) { console.log(name, age)}fn1() // curry 30// 2.写法二:解构+默认值function fn2({ name = 'curry', age = 30 } = {}) { console.log(name, age)}fn2() // curry 30注意:有默认值的参数一般会放到最后,在JS中函数都会有一个length属性,length长度代表函数参数个数,但是有默认值的参数是不会被计算在内的。但是如果将有默认值的参数放在中间,那么后面的参数也不会被计算在内的。
function fn1(x, y, z) {}console.log(fn1.length) // 3function fn2(x, y, z = 30) {}console.log(fn2.length) // 2function fn3(x, y = 30, z) {}console.log(fn3.length) // 1ES6中引用了剩余参数,可以将不定数量的参数放入到一个数组中,如果最后一个参数是以...为前缀的,那么它会将剩余的参数放入到该参数中,并且作为一个数组。
剩余参数和arguments有什么区别呢?
function foo(m, n, ...args) { console.log(m, n, args) console.log(arguments) // [Arguments] { '0': 10, '1': 20, '2': 30, '3': 40, '4': 50 }}foo(10, 20, 30, 40, 50) // 10 20 [ 30, 40, 50 ]相比于普通函数,箭头函数有一下几个特殊点:
const fn = () => { console.log(this) // console.log(argments) // ReferenceError: argments is not defined}fn() // window对象console.log(fn.prototype) // undefined展开语法(spread syntax)可以在函数调用或数组构造是,将数组表示或者字符串在语法层面展开,还可以在构造字面量对象时,将对象表达式按键值对的方式展开。
展开语法的主要使用场景:在函数调用时和数组构造时使用:
const nums = [1, 2, 3]const str = 'abc'function fn(x, y, z) { console.log(x, y, z)}// 函数调用时fn(...nums) // 1 2 3fn(...str) // a b c// 数组构造时const newNums1 = [...nums, 4, 5]const newNums2 = [...nums, ...str]console.log(newNums1) // [ 1, 2, 3, 4, 5 ]console.log(newNums2) // [ 1, 2, 3, 'a', 'b', 'c' ]ES6中规范了二进制和八进制的写法。
const num1 = 188 // 十进制const num2 = 0b101 // 二进制const num3 = 0o567 // 八进制const num4 = 0x8cf // 十六进制// 打印转成对应的十进制数console.log(num1, num2, num3, num4) // 188 5 375 2255在ES6之前,对象属性名都是字符串形式,很容易造成属性名冲突,Symbol是ES6中新增的一个基本数据类型,可用来生成一个独一无二的值。
作为属性名:
const s1 = Symbol()const s2 = Symbol()const s3 = Symbol()// 对比调用Symbol生成的值console.log(s1 === s2) // false// Symbol值作为对象key// 写法一:定义对象字面量时使用const obj = { [s1]: 'aaaa'}// 写法二:对象新增属性obj[s2] = 'bbbb'// 写法三:通过Object.defineProperty()Object.defineProperty(obj, s3, { enumerable: true, configurable: true, writable: true, value: 'cccc'})console.log(obj) // { [Symbol()]: 'aaaa', [Symbol()]: 'bbbb', [Symbol()]: 'cccc' }作为属性值:
const s1 = Symbol()const obj = { name: 'curry', age: s1}console.log(obj) // { name: 'curry', age: Symbol() }注意:Symbol作为属性名时,不能通过.方式来获取,也就是obj.s1,只能通过obj[s1]的方式获取。并且在通过Object.keys()获取对象所有的key时,是获取不到这些Symbol的,可以借助Object.getOwnPropertySymbols()来获取所有类型为Symbol的key。
console.log(obj.s1) // undefinedconsole.log(obj[s1]) // aaaaconsole.log(obj[s2]) // bbbb// 使用Object.keys获取对象所有key并打印,发现数组中是没有Symbol的keyconsole.log(Object.keys(obj)) // []// 使用Object.getOwnPropertySymbols(obj)获取所有的Symbol的keyconsole.log(Object.getOwnPropertySymbols(obj)) // [ Symbol(), Symbol(), Symbol() ]延伸:Symbol的作用就是给我们创建一个独一无二的值,如果我们想创建一个相同的Symbol可以怎么做呢?
Symbol.for()来做到这一点;Symbol.keyFor()方法来获取对应的key;// 通过Symbol.for(描述)创建并传入相同描述const s1 = Symbol.for('aaaa')const s2 = Symbol.for('aaaa')console.log(s1 === s2) // true// 拿到s1传入的值const key = Symbol.keyFor(s1)console.log(key) // aaaa// 将拿到的值又传给s3const s3 = Symbol.for(key)console.log(s3 === s1) // trueconsole.log(s3 === s2) // true在ES6之前,存储数据的结构主要有两种,分别是数组和对象。在ES6中新增了另外两种数据结构:Set、Map,以及它们另外形式的WeakSet、WeakMap。下面就先来看看Set和WeakSet。
(1)Set:用于保存数据,类似于数组,与数组不同的是Set中的元素是不能重复的。
Set的基本使用:
// 1.创建一个Set结构const set = new Set()// 2.往set中添加元素set.add(30)set.add(30) // 相同的基本数据类型只会保留一个set.add('abc')set.add(undefined)set.add({})set.add({}) // 对象可以重复的原因是,对象存放的是内存地址set.add(NaN)set.add(NaN) // 为什么NaN也不能重复,因为在Set内部会视NaN为同一个东西console.log(set) // Set(6) { 30, 'abc', undefined, {}, {}, NaN }Set常见的属性:
size:返回Set中元素的个数;
console.log(set.size) // 6Set常见的方法:
// addconsole.log(set.add(30)) // Set(1) { 30 }console.log(set.add(60)) // Set(2) { 30, 60 }console.log(set.add(90)) // Set(2) { 30, 60, 90 }// deleteconsole.log(set.delete(40)) // 未找到40,返回falseconsole.log(set.delete(30)) // true// hasconsole.log(set.has(60)) // trueconsole.log(set.has(30)) // false// forEachset.forEach(item => { console.log(item) // 60 90})// for...offor (const item of set) { console.log(item) // 60 90}// clearset.clear()console.log(set) // Set(0) {}(2)WeakSet:也要求内部元素不能重复。
WeakSet与Set的区别:
WeakSet常见方法:add(value)、delete(value)、has(value),没有clear和forEach;
WeakSet的基本使用:
const wSet = new WeakSet()// 只能存放对象类型// wSet.add(10) // TypeError: Invalid value used in weak setwSet.add({ name: 'curry', age: 30 })wSet.add([1, 2, 3])下面来讲讲Map和WeakMap,主要用于存储映射关系。
(1)Map:对于普通对象存储映射关系,只能使用字符串或者Symbol作为属性名,如果普通对象使用对象来作为key的话,会自动将对象转成字符串,但是Map允许我们使用对象作为key。
const obj1 = { name: 'curry', age: 30 }const obj = { [obj1]: 'aaaa'}// 普通对象使用对象作为key,对象会自动转成字符串[object Object]console.log(obj) // { '[object Object]': 'aaaa' }Map的基本使用:
const obj1 = { name: 'curry', age: 30 }const obj2 = { name: 'kobe', age: 24 }// 方式一:创建map后,通过set添加属性const map1 = new Map()map1.set(obj1, 'aaaa')map1.set(obj2, 'bbbb')// 方式二:创建map时,传入一个数组const map2 = new Map([ [obj1, 'aaaa'], [obj2, 'bbbb']])console.log(map1)console.log(map2)
Map常见的属性:
size:返回Map中元素的个数;
console.log(map1.size) // 2Map常见的方法:与Set很相似,设置和获取属性不太一样。
const map = new Map()const obj = { name: 'curry', age: 30 }// setmap.set(obj, 'aaaa')map.set('bbbb', 1234)map.set(11, 'cccc')// getconsole.log(map.get(obj)) // aaaa// deleteconsole.log(map.delete(11)) // trueconsole.log(map.delete(22)) // false// hasconsole.log(map.has('bbbb')) // trueconsole.log(map.has('abc')) // false// forEachmap.forEach((value, key) => { console.log(key, value) /* { name: 'curry', age: 30 } aaaa bbbb 1234 */})// clearmap.clear()console.log(map) // Map(0) {}如果map使用for...of遍历,看一下遍历出来的值是什么样子的:
// 这里取出的item是一个个数组,数组第一个元素是key,第二个元素是valuefor (const item of map) { console.log(item)}// 所以可以在取值的时候对item进行解构for (const [key, value] of map) { console.log(key, value)}
(2)WeakMap:也是以键值对的形式存在。
在ES7之前,判断数组中包含某一个元素,一般可以用indexOf判断是否为-1,ES7给我们提供了includes方法来判断数组中是否包含指定元素,返回boolean类型;
arr.includes(valueToFind[, fromIndex])array.length + fromIndex的位置开始查找(默认值为0);const names = ['curry', 'kobe', NaN]console.log(names.includes('curry')) // trueconsole.log(names.includes('klay')) // falseconsole.log(names.includes('curry', 1)) // falseconsole.log(names.indexOf(NaN)) // -1console.log(names.includes(NaN)) // true注意:includes方法是可以判断NaN是否存在的,因为includes的内部实现对NaN采用isNaN方法进行判断。

在ES7之前,计算数字的指数需要通过Math.pow方法来完成,在ES7中,增加了
**运算符,可以来计算指数。
计算2的3次方:
const res1 = Math.pow(2, 3)const res2 = 2 ** 3console.log(res1, res2) // 8 8我们知道可以使用Object.keys获取一个对象的所有key,ES8给我们提供了Object.values来获取所有的value值。
const obj = { name: 'curry', age: 30, team: '勇士'}// 传入一个对象console.log(Object.values(obj)) // [ 'curry', 30, '勇士' ]// 传入一个字符串,达到split的效果console.log(Object.values('abc')) // [ 'a', 'b', 'c' ]通过Object.entries()可以获取到一个二维数组,数组中会存放可枚举的键值对数组,数组元素分别为对象的key和value。
const obj = { name: 'curry', age: 30, team: '勇士'}// 传入一个对象console.log(Object.entries(obj)) // [ [ 'name', 'curry' ], [ 'age', 30 ], [ 'team', '勇士' ] ]for (const [key, value] of Object.entries(obj)) { console.log(key, value) /* name curry age 30 team 勇士 */}// 传入一个数组,下标作为第一个元素console.log(Object.entries(['curry', 'kobe', 'klay'])) // [ [ '0', 'curry' ], [ '1', 'kobe' ], [ '2', 'klay' ] ]// 传入一个字符串,下标作为第一个元素console.log(Object.entries('abc')) // [ [ '0', 'a' ], [ '1', 'b' ], [ '2', 'c' ] ]如果需要对字符串进行前后填充,来实现某种展示格式,ES8中提供了padStart和padEnd方法,分别可以对字符串进行首位填充。
const str = 'ssssssssss'// 如果指定填充的位数小于等于str的长度,就不会进行填充// 指定的位数需大于str的长度,就会填充str长度减去指定位数// 如下指定了15,最终填充的只有5位,因为str的长度为10console.log(str.padStart(15, '*')) // *****ssssssssssconsole.log(str.padEnd(15, '-')) // ssssssssss-----应用场景:字符串的填充可以用于对身份证、银行卡进行位数隐藏。
const bankCard = '2034399002125581'// 截取银行卡后四位数组const lastFourNum = bankCard.slice(-4)// 将前面数组全部填充为*const finalBankCard = lastFourNum.padStart(bankCard.length, '*')console.log(finalBankCard) // ************5581Object.getOwnPropertyDescriptors()方法用来获取一个对象的所有自身属性的描述符。
const obj = {}Object.defineProperties(obj, { name: { configurable: false, writable: false, enumerable: false, value: 'curry' }, age: { configurable: true, writable: true, enumerable: true, value: 30 }})console.log(Object.getOwnPropertyDescriptors(obj))
在前面讲了,数组是可以使用展开语法的,在ES9中,在构建对象字面量时,也可以使用展开语法了。
const obj1 = { name: 'curry', age: 30}const newObj1 = { ...obj1, team: '勇士' }console.log(newObj1) // { name: 'curry', age: 30, team: '勇士' }注意:对象的展开运算符只能实现浅拷贝,如果对象内部还包含引用类型的值,就会指向同一地址空间。
const obj = { name: 'curry', age: 30, friends: ['kobe', 'klay']}const newObj = { ...obj }newObj.friends.push('james')console.log(newObj) // { name: 'curry', age: 30, team: '勇士' }console.log(obj) // { name: 'curry', age: 30, friends: [ 'kobe', 'klay', 'james' ] }(1)flat方法
按照一个可指定的深度递归遍历数组,并将所有的元素和遍历到的子数组合并为一个新数组返回。(可用于数组扁平化)
const nums = [1, 2, [3, 3], [4, [5, 5]]]// 对数组进行降维处理console.log(nums.flat(1)) // [ 1, 2, 3, 3, 4, [ 5, 5 ] ]console.log(nums.flat(2)) // [ 1, 2, 3, 3, 4, 5, 5 ]// 如果不知道数组嵌套了多少层,可直接指定Infinityconsole.log(nums.flat(Infinity)) // [ 1, 2, 3, 3, 4, 5, 5 ](2)flatMap方法
首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。
const arr = [[1, 2, 3, 4], ['a', 'b','c', 'd']]// 数组自动降一维const newArr = arr.flatMap(item => { return item})console.log(newArr) // [ 1, 2, 3, 4, 'a', 'b', 'c', 'd' ]在前面讲了可以通过Object.entries()将一个对象转换成键值对数组,而Object.fromEntries()可以将键值对列表转换成对象。
const entries = [ ['name', 'curry'], ['age', 30]]const obj = Object.fromEntries(entries)console.log(obj) // { name: 'curry', age: 30 }应用场景:解析url的query部分,将其转成一个对象。
const url = 'http://127.0.0.1:8000/search?name=curry&age=30'const queryStr = url.slice(url.indexOf('?') + 1, url.length)console.log(queryStr) // name=curry&age=30// URLSearchParams:可用于处理url的查询字符串const queryParams = new URLSearchParams(queryStr)console.log(queryParams) // URLSearchParams { 'name' => 'curry', 'age' => '30' }const paramObj = Object.fromEntries(queryParams)console.log(paramObj) // { name: 'curry', age: '30' }去除一个字符串首尾空格可以通过trim()方法,而trimStart和trimEnd方法分别可以单独去除字符串前或后的空格。
// 这里以·代表空格const str = '····ssss···'console.log(str.trim()) // ssssconsole.log(str.trimStart()) // ssss··· console.log(str.trimEnd()) // ····ssss在前面讲了Symbol类型,在创建一个Symbol类型的值时,还可以传入指定的描述符。
const s1 = Symbol('aaaa')const s2 = Symbol('bbbb')console.log(s1.description) // aaaaconsole.log(s2.description) // bbbb在JavaScript中,如果数字过大,可能是不正确的,先看看JavaScript提供给我们的最大值和最小值是多少。
const maxNum = Number.MAX_SAFE_INTEGERconst minNum = Number.MIN_SAFE_INTEGERconsole.log(maxNum) // 9007199254740991console.log(minNum) // -9007199254740991如果给最大值再加大数值,很明显数值是不正确的:
console.log(maxNum + 1) // 9007199254740992console.log(maxNum + 2) // 9007199254740992所以,ES11引入了新的数据类型BigInt,可用于表示很大的整数:
n;n转成BigInt;BigInt()方法进行转类型;const bigInt = 9007199254740991nconsole.log(bigInt + 2n) // 9007199254740993nconsole.log(bigInt + bigInt) // 18014398509481982n如果
||不能对空字符串和0进行很好的判断,就可以使用??。
const test1 = ''const test2 = 0const test3 = nullconst test4 = undefinedconst res1 = test1 || 'default'const res2 = test2 || 'default'console.log(res1) // defaultconsole.log(res2) // default// ??认为空字符串和0是真值的const res3 = test1 ?? 'default'const res4 = test2 ?? 'default'console.log(res3) // ''console.log(res4) // 0// 只有当??前面的值为null或者undefined,才会使用后面的值const res5 = test3 ?? 'default'const res6 = test4 ?? 'default'console.log(res5) // defaultconsole.log(res6) // default可选链(Optional Chaining)的主要作用就是让代码在进行null和undefined判断时更加清晰和简洁,确保我们访问对象属性是安全的(因为从undefined里面取值是会报错的)。
const obj = { name: 'curry', friend: { name: 'kobe', age: 24 }}// 先判断obj中是否有friend属性,然后再判断friend中是否有name属性console.log(obj?.friend?.name) // kobe// console.log(obj.teammate.name) // TypeError: Cannot read property 'name' of undefined// obj中没有teammate属性,所以就直接返回undefined,不会再从undefined中取name了,不会报错影响后面程序运行console.log(obj?.teammate?.name) // undefined在ES11之前获取JavaScript的全局对象在不同的环境下的获取方式不同:
ES11中,对我们获取全局对象进行统一规范:
console.log(globalThis)浏览器中:

node中:

FinalizationRegistry对象可以让你在对象被垃圾回收时请求一个回调。
let obj1 = { name: 'curry', age: 30 }let obj2 = { name: 'kobe', age: 24 }// 实例化注册表const register = new FinalizationRegistry(value => { console.log(`${value}对象被销毁了`)})// 注册obj1和obj2,并指定其值register.register(obj1, 'obj1')register.register(obj2, 'obj2')// 将两个对象销毁obj1 = nullobj2 = null需要借助浏览器的GC来进行测试,当两个对象被真正回收了,就会调用清理回调,打印对应内容:

在前面讲了WeakSet和WeakMap中的元素对对象的引用都是弱引用,WeakRef就可以专门实现对一个对象进行弱引用,也就是说该对象被GC回收时,是不会看它是否有弱引用的,有没有弱引用一样被回收。
可以结合上面的FinalizationRegistry进行测试:
deref()来访问对象属性;let obj = { name: 'curry', age: 30 }// 创建一个弱引用weakObj指向对象{ name: 'curry', age: 30 }let weakObj = new WeakRef(obj)// 拿到{ name: 'curry', age: 30 }对象// console.log(weakObj.deref())// console.log(weakObj.deref().name) // curry// console.log(weakObj.deref().age) // 30const register = new FinalizationRegistry(value => { console.log(`${value}对象被销毁了`)})register.register(obj, 'obj')// 去掉obj对对象{ name: 'curry', age: 30 }的引用obj = null// 等对象回收后再打印setTimeout(() => { // 注意:当弱引用的对象被GC回收后,weakObj.deref()的值为undefined // 如果不想报错,可以使用可选链或者逻辑与 console.log(weakObj.deref()?.name) console.log(weakObj.deref() && weakObj.deref().name)}, 10000)
ES12为我们提供了三种逻辑赋值运算:
||=:逻辑或赋值运算;
let msg = undefinedmsg ||= 'default'console.log(msg) // default/* 等同于: msg = msg || 'default'*/&&=:逻辑与赋值运算;
let obj = { name: 'curry', age: 30}// 在obj有值的情况下,将obj赋值为obj.nameobj &&= obj.nameconsole.log(obj) // curry/* 等同于: obj = obj && obj.name*/??=:逻辑空赋值运算;
let msg = 0// 当msg为null或undefined情况下,将msg赋值为default,这里为0,所以值还是0msg ??= 'default'console.log(msg) // 0/* 等同于: msg = msg ?? 'default'*/注意:该新增特性可能过新,可能出现node版本不支持的情况,可以在浏览器中打印查看。
当数值过长时,ES12允许我们使用
_进行连接,方便阅读。
const num = 100_000_000console.log(num) //100000000ES12提供了一个replaceAll方法,该返回一个新字符串,新字符串所有满足
pattern的部分都已被replacement替换。pattern可以是一个字符串或一个RegExp,replacement可以是一个字符串或一个在每次匹配被调用的函数。
const newStr = str.replaceAll(regexp|substr, newSubstr|function)将所有的a替换为b:
const str = 'ababababab'// 字符串const newStr1 = str.replaceAll('a', 'b')// 正则const regex = /a/gconst newStr2 = str.replace(regex, 'b')console.log(newStr1) // bbbbbbbbbbconsole.log(newStr2) // bbbbbbbbbb注意:该新增特性可能过新,可能出现node版本不支持的情况,可以在浏览器中打印查看。
本篇文字只总结了ES6-ES12部分简单知识点,还有一些其它ES6之后新增的特性,如Promise、迭代器、生成器、async、await等等,将会在后续的文章中进行整理。