ES6
1.Let重复申明会报错
在申明let/const类型数据之前进行该数据操作会报错,而var类型的数据会存在变量提升,
所以只会只是undefined,在let/const数据声明使用前的这一段时间就是暂时性死区
2.const能push但是不能用等号赋值
3.rest参数,获取函数实参
4.symbol 不能进行运算,不能用for in 遍历,可以使用Eeflect.ownKeys来获取键值 symbol.for("q")===symbol.for("q")"
5. lterator 迭代器 自定义数组 具有[symbol.iterator]属性,
都可以for of
6.生成器 generator yield 通过next执行,next传参为上一个yield语句返回结果
7.class或者function中的静态变量数组类,实例new出来是没法获取到的
8.class extends继承使用super,类似于使用了继承对象的constructor方法
9. class get set 中set必须有一个形参
10.number.EPSTION 表示最小精度
11.二进制0b开头 八进制0o开头
12.Math.trunc把小数点抹去 Math.sign检测正数负数0
13.let` 和 `const`
14.Async await 是generator语法糖
15.Generator是分段方法,遇到yield会暂停
| | var | let | const |
| ------- | --- | --- | ----- |
| 变量提升 | √ | × | × |
| 全局变量 | √ | × | × |
| 重复声明 | √ | × | × |
| 重新赋值 | √ | √ | × |
| 暂时性死区 | × | √ | √ |
| 块作用域 | × | √ | √ |
| 只声明不初始化 | √ | √ | × |
-
类(
Class) 在ES6之前,如果我们要生成一个实例对象,传统的方法就是写一个构造函数,例子如下: class为构造函数语法糖function Person(name, age) { this.name = name this.age = age } Person.prototype.information = function () { return 'My name is ' + this.name + ', I am ' + this.age }但是在
ES6之后,我们只需要写成以下形式:class Person { constructor(name, age) { this.name = name this.age = age } information() { return 'My name is ' + this.name + ', I am ' + this.age } }
0.for…of for ... in ; for ... of 区别
- for ... in 获取的是对象的键名;for ... of 遍历获取的是对象的键值
- for ... in 会遍历对象的整个原型链,性能非常差,不推荐使用;而 for ... of 只遍历当前对象,不会遍历原型链
- 对于数组的遍历,for ... in 会返回数组中所有可枚举的属性(包括原型链上可枚举的属性);for ... of 只返回数组的下标对应的属性值
- 对于普通对象,没有部署原生的 iterator 接口,直接使用 for...of 会报错,也可以使用 Object.keys(obj) 方法将对象的键名生成一个数组,然后遍历这个数组
- forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效;for...of 循环可以与 break、continue 和 return 配合使用,跳出循环
- for...in 循环主要是为了遍历对象而生,不适用于遍历数组;for...of 循环可以用来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象
-
Symbol
symbol是一种基本数据类型,表示独一无二的值。Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。 每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。const symbol1 = Symbol(); const symbol2 = Symbol(42); const symbol3 = Symbol('foo'); console.log(typeof symbol1); // "symbol" console.log(symbol3.toString()); // "Symbol(foo)" console.log(Symbol('foo') === Symbol('foo')); // false -
迭代器(Iterator)/ 生成器(Generator) 迭代器(
Iterator)是一种迭代的机制,为各种不同的数据结构提供统一的访问机制。任何数据结构只要内部有Iterator接口,就可以完成依次迭代操作。 一旦创建,迭代器对象可以通过重复调用next()显式地迭代,从而获取该对象每一级的值,直到迭代完,返回{ value: undefined, done: true }。function* makeRangeIterator(start = 0, end = Infinity, step = 1) { for (let i = start; i < end; i += step) { yield i; } } var a = makeRangeIterator(1,10,2) a.next() // {value: 1, done: false} a.next() // {value: 3, done: false} a.next() // {value: 5, done: false} a.next() // {value: 7, done: false} a.next() // {value: 9, done: false} a.next() // {value: undefined, done: true} -
Set / WeakSet
Set对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5] console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]WeakSet结构与Set类似,但区别有以下两点:-
WeakSet对象中只能存放对象引用,不能存放值,而Set对象都可以。 -
WeakSet对象中存储的对象值都是被弱引用的,如果没有其他的变量或属性引用这个对象值,则这个对象值会被当成垃圾回收掉。正因为这样,WeakSet对象是无法被枚举的,没有办法拿到它包含的所有元素。
const ws = new WeakSet() const obj = {} const foo = {} ws.add(window) ws.add(obj) ws.has(window) // true ws.has(foo) // false, 对象 foo 并没有被添加进 ws 中 ws.delete(window) // 从集合中删除 window 对象 ws.has(window) // false, window 对象已经被删除了 ws.clear() // 清空整个 WeakSet 对象 -
-
Map / WeakMap
Map对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。甚至可以使用NaN来作为键值。const myMap = new Map(); myMap.set(NaN, "not a number"); myMap.get(NaN); // "not a number" const otherNaN = Number("foo"); myMap.get(otherNaN); // "not a number"WeakMap对象是一组键 / 值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。跟Map的区别与Set跟WeakSet的区别相似。const o1 = {}; const o2 = function(){}; const o3 = window; const wm1 = new WeakMap(); wm1.set(o1, 37); wm1.has(o1); // true wm1.delete(o1); wm1.has(o1); // false wm1.set(o2, "azerty"); wm1.get(o2); // "azerty" wm1.has(o2); // true const wm2 = new WeakMap(); wm2.set(o1, o2); // value可以是任意值,包括一个对象 wm2.get(o2); // undefined,wm2中没有o2这个键 wm2.has(o2); // false wm2.set(o3, undefined); wm2.get(o3); // undefined,值就是undefined wm2.has(o3); // true (即使值是undefined) wm2.set(wm1, wm2); // 键和值可以是任意对象,甚至另外一个WeakMap对象 const wm3 = new WeakMap(); wm3.set(o1, 37); wm3.get(o1); // 37 wm3.clear(); wm3.get(o1); // undefined,wm3已被清空 -
Proxy / Reflect
Proxy对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。Reflect是一个内置的对象,它提供拦截JavaScript操作的方法。这些方法与Proxy的方法相同。Reflect不是一个函数对象,因此它是不可构造的。const observe = (data, callback) => { return new Proxy(data, { get(target, key) { return Reflect.get(target, key) }, set(target, key, value, proxy) { callback(key, value); target[key] = value; return Reflect.set(target, key, value, proxy) } }) } const FooBar = { open: false }; const FooBarObserver = observe(FooBar, (property, value) => { property === 'open' && value ? console.log('FooBar is open!!!') : console.log('keep waiting'); }); console.log(FooBarObserver.open) // false FooBarObserver.open = true // FooBar is open!!! FooBarObserver.open = false // keep waiting -
Regex对象的扩展
-
u 修饰符: 为了处理码点大于
\uFFFF的Unicode字符(也就是说,会正确处理四个字节的UTF-16编码);\uD83D\uDC2A是一个字符,但是es5不支持四个字节的UTF-16,会将其识别成两个字符;加了u修饰符之后,es6会将其识别成一个字符。// i 修饰符:不区分大小写 /[a-z]/i.test('\u212A') // false /[a-z]/iu.test('\u212A') // true -
y 修饰符:“粘连”(sticky)修饰符
y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。var s = 'aaa_aa_a'; var r1 = /a+/g; var r2 = /a+/y; r1.exec(s) // ["aaa"] r2.exec(s) // ["aaa"] r1.exec(s) // ["aa"] r2.exec(s) // null -
查看RegExp构造函数的修饰符
new RegExp(/abc/ig, 'i').flags // "i"
-
-
Array 对象的扩展
-
Array.from()用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。Array.from('foo') // ["f", "o", "o"] // 扩展运算符(...)也可以将某些数据结构转为数组 [ ...document.querySelectorAll('div') ] // NodeList对象 Array.from({ length: 3 }) // [ undefined, undefined, undefined ] Array.from([1, 2, 3], x => x + x) // [2, 4, 6] -
Array.of():用于将一组值,转换为数组Array.of() // [] Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1 // 这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。 Array() // [] Array(7) // [empty, empty, empty, empty, empty, empty] Array(3, 11, 8) // [3, 11, 8] -
数组实例的
copyWithin()在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组,会修改当前数组。Array.prototype.copyWithin(target, start = 0, end = this.length)它接受三个参数。这三个参数都应该是数值,如果不是,会自动转为数值。-
target(必需):从该位置开始替换数据。
-
start(可选):从该位置开始读取数据,默认为0。如果为负值,表示倒数。
-
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
['a', 'b', 'c', 'd', 'e'].copyWithin(0, 3, 4) // ["d", "b", "c", "d", "e"] [1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5] [1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5] -
-
数组实例的
find() 和 findIndex() -
数组实例的
fill():fill方法使用给定值,填充一个数组['a', 'b', 'c'].fill(7) // [7, 7, 7] new Array(3).fill(7) // [7, 7, 7] // 可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置 ['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c'] [1, 2, 3, 4].fill(5, 1) // [1, 5, 5, 5] -
数组实例的
entries(),keys() 和 values()/* * 用于遍历数组,都返回一个遍历器对象,可以用 for...of 循环进行遍历 * 唯一的区别是 keys() 是对键名的遍历、values() 是对键值的遍历、entries() 是对键值对的遍历 */ for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b" -
数组的空位:明确将空位转为
undefined
-
ES7
数组实例的 `includes()` 返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 `includes` 方法类似
```
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, NaN].includes(NaN); // true
```
该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,
如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。
```
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
```
> 另外,`Map` 和 `Set` 数据结构有一个 `has` 方法,需要注意与 `includes` 区分。
1. `Map` 结构的has方法,
是用来查找键名的,比如 `Map.prototype.has(key)、WeakMap.prototype.has(key)、Reflect.has(target, propertyKey)`。
2. `Set` 结构的 `has` 方法,是用来查找值的,比如 `Set.prototype.has(value)、WeakSet.prototype.has(value)`。
幂运算符 `**`
```
console.log(2**10) // 1024 类似于Math.pow(2, 10)
console.log(Math.pow(2, 10)) // 1024
```
模板字符串(Template string) 自 `ES7` 起,带标签的模版字面量遵守以下转义序列的规则:
- `Unicode` 字符以 `"\u"` 开头,例如 `\u00A9`
- `Unicode` 码位用"\u{}"表示,例如 `\u{2F804}`
- 十六进制以 `"\x"` 开头,例如 `\xA9`
- 八进制以 `""` 和数字开头,例如 `\251`
ES8
Object.entries () 将对象转换为二维数组
Object.values():返回一个给定对象自身的所有可枚举属性值的数组
```
const object1 = {
a: 'somestring',
b: 42,
c: false
}
console.log(Object.values(object1)) // ["somestring", 42, false]
```
Object.entries():返回一个给定对象自身可枚举属性的键值对数组
```
const object1 = {
a: 'somestring',
b: 42
}
console.log(Object.entries(object1)) // [["a","somestring"],["b",42]]
for (let [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`)
}
// "a: somestring"
// "b: 42"
```
padStart():用另一个字符串填充当前字符串(重复,如果需要的话),以便产生的字符串达到给定的长度。填充从当前字符串的开始(左侧)应用的。
```
const str1 = '5'
console.log(str1.padStart(4, '0')) // "0005"
// 若无第二个参数,用空格填充
console.log(str1.padStart(4)) // " 5"
```
padEnd():用一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充。
```
const str1 = 'Breaded Mushrooms'
console.log(str1.padEnd(25, '.')) // "Breaded Mushrooms........"
const str2 = '200'
console.log(str2.padEnd(5)) // "200 "
```
函数参数结尾逗号
SharedArrayBuffer对象 `SharedArrayBuffer` 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,类似于 `ArrayBuffer` 对象,它们都可以用来在共享内存(`shared memory`)上创建视图。与 `ArrayBuffer` 不同的是,`SharedArrayBuffer` 不能被分离。
```
// 参数length指所创建的数组缓冲区的大小,以字节(byte)为单位
let sab = new SharedArrayBuffer(1024) // 创建一个1024字节的缓冲
```
Atomics对象 `Atomics对象` 提供了一组静态方法用来对 `SharedArrayBuffer` 对象进行原子操作。
- `Atomics.add()`:将指定位置上的数组元素与给定的值相加,并返回相加前该元素的值。
- `Atomics.and()`:将指定位置上的数组元素与给定的值相与,并返回与操作前该元素的值。
- `Atomics.compareExchange()`:如果数组中指定的元素与给定的值相等,则将其更新为新的值,并返回该元素原先的值。
- `Atomics.exchange()`:将数组中指定的元素更新为给定的值,并返回该元素更新前的值。
- `Atomics.load()`:返回数组中指定元素的值。
- `Atomics.or()`:将指定位置上的数组元素与给定的值相或,并返回或操作前该元素的值。
- `Atomics.store()`:将数组中指定的元素设置为给定的值,并返回该值。
- `Atomics.sub()`:将指定位置上的数组元素与给定的值相减,并返回相减前该元素的值。
- `Atomics.xor()`:将指定位置上的数组元素与给定的值相异或,并返回异或操作前该元素的值。
- `Atomics.wait()`:检测数组中某个指定位置上的值是否仍然是给定值,是则保持挂起直到被唤醒或超时。返回值为 “ok”、“not-equal” 或 “time-out”。调用时,如果当前线程不允许阻塞,则会抛出异常(大多数浏览器都不允许在主线程中调用 wait())。
- `Atomics.wake()`:唤醒等待队列中正在数组指定位置的元素上等待的线程。返回值为成功唤醒的线程数量。
- `Atomics.isLockFree(size)`:可以用来检测当前系统是否支持硬件级的原子操作。对于指定大小的数组,如果当前系统支持硬件级的原子操作,则返回 true;否则就意味着对于该数组,Atomics 对象中的各原子操作都只能用锁来实现。此函数面向的是技术专家。
Object.getOwnPropertyDescriptors():用来获取一个对象的所有自身属性的描述符
```
const obj = {
foo: 123,
get bar() { return 'abc' }
};
Object.getOwnPropertyDescriptors(obj)
// { foo:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: bar],
// set: undefined,
// enumerable: true,
// configurable: true } }
```
- 浅拷贝一个对象 [`Object.assign()`](https://links.jianshu.com/go?to=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FJavaScript%2FReference%2FGlobal_Objects%2FObject%2Fassign) 方法只能拷贝源对象的可枚举的自身属性,同时拷贝时无法拷贝属性的特性们,而且访问器属性会被转换成数据属性,也无法拷贝源对象的原型,该方法配合 [`Object.create()`](https://links.jianshu.com/go?to=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FJavaScript%2FReference%2FGlobal_Objects%2FObject%2Fcreate) 方法可以实现上面说的这些。
```
Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
);
```
- 创建子类 创建子类的典型方法是定义子类,将其原型设置为超类的实例,然后在该实例上定义属性。这么写很不优雅,特别是对于 getters 和 setter 而言。 相反,您可以使用此代码设置原型:
```
function superclass() {}
superclass.prototype = {
// 在这里定义方法和属性
};
function subclass() {}
subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({
// 在这里定义方法和属性
}));
```
\
ES9
1.对正则捕获到的数据进行分组
2.正则 正向断言?=
let str='JS5211314你知道么555啦啦啦'
const reg=/\d+(?=啦)/
const result=reg.exec(str)
反向断言
const reg=/(?<=么)\d+/
const result=reg.exec(str)
3.正则//s 结尾添加s 则点号可以匹配任意字符
-
for await…of
for await...of语句创建一个循环,该循环遍历异步可迭代对象以及同步可迭代对象,包括: 内置的String,Array,类似数组对象 (例如arguments或NodeList),TypedArray,Map,Set和用户定义的异步/同步迭代器。其会调用自定义迭代钩子,并为每个不同属性的值执行语句。async function* asyncGenerator() { var i = 0 while (i < 3) { yield i++ } } (async function() { for await (num of asyncGenerator()) { console.log(num) } })() // 0 // 1 // 2 -
模板字符串(Template string)
ES9开始,模板字符串允许嵌套支持常见转义序列,移除对ECMAScript在带标签的模版字符串中转义序列的语法限制。 -
正则表达式 Unicode 转义 正则表达式中的
Unicode转义符允许根据Unicode字符属性匹配Unicode字符。 它允许区分字符类型,例如大写和小写字母,数学符号和标点符号。// 匹配所有数字 const regex = /^\p{Number}+$/u; regex.test('²³¹¼½¾') // true regex.test('㉛㉜㉝') // true regex.test('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ') // true // 匹配所有空格 \p{White_Space} // 匹配各种文字的所有字母,等同于 Unicode 版的 \w [\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}] // 匹配各种文字的所有非字母的字符,等同于 Unicode 版的 \W [^\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}] // 匹配 Emoji /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu // 匹配所有的箭头字符 const regexArrows = /^\p{Block=Arrows}+$/u; regexArrows.test('←↑→↓⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇧⇩') // true -
正则表达式 s/dotAll 模式
JS正则增加了一个新的标志s用来表示dotAll,这可以匹配任意字符。const re = /foo.bar/s; // 等价于 const re = new RegExp('foo.bar', 's'); re.test('foo\nbar'); // true re.dotAll; // true re.flags; // "s"
具名组匹配
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
对象扩展操作符
fetch(url)
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
.finally(() => {
console.log('结束')
})
ES10
1.Object.fromEntries() 获取key和value 将数组转换为对象
2.flatMap 两个操作的结合 flat Map
3.Symbol.prototype.description 获取symbol的描述 s.description
数组实例的 flat() 用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。参数 depth 表示要提取嵌套数组的结构深度,默认值为 1。
console.log([1 ,[2, 3]].flat()); // [1, 2, 3]
// 指定转换的嵌套层数
console.log([1, [2, [3, [4, 5]]]].flat(2)); // [1, 2, 3, [4, 5]]
// 不管嵌套多少层【使用 Infinity 作为深度,展开任意深度的嵌套数组】
console.log([1, [2, [3, [4, 5]]]].flat(Infinity)); // [1, 2, 3, 4, 5]
// 自动跳过空位【会移除数组中的空项】
console.log([1, [2, , 3]].flat()); // [1, 2, 3]
// 传入 <=0 的整数将返回原数组,不“拉平”
console.log([1, [2, [3, [4, 5]]]].flat(0)); // [1, [2, [3, [4, 5]]]]
console.log([1, [2, [3, [4, 5]]]].flat(-10)); // [1, [2, [3, [4, 5]]]]
数组实例的 flatMap() 首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 和连着深度值为1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。
[1, 2, 3, 4].flatMap(x => x * 2); // [2, 4, 6, 8]
[1, 2, 3, 4].flatMap(x => [x * 2]); // [2, 4, 6, 8]
[1, 2, 3, 4].flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]
[1, 2, 3, 4].map(x => [x * 2]); // [[2], [4], [6], [8]]
字符串实例的 trimStart() / trimLeft() / trimEnd() / trimRight() 去除字符首或尾的空格,trimStart() 跟 trimEnd() 才是标准方法,trimLeft() 跟 trimRight() 只是别名
Object.fromEntries() 把键值对列表转换为一个对象,它是 Object.entries() 的反函数。
const entries = new Map([ ['foo', 'bar'],
['baz', 42]
])
console.log(Object.fromEntries(entries)) // Object { foo: "bar", baz: 42 }
Symbol.prototype.description 通过工厂函数 Symbol() 创建符号时,您可以选择通过参数提供字符串作为描述:
Symbol('desc').toString(); // "Symbol(desc)"
Symbol('desc').description; // "desc"
Symbol('').description; // ""
Symbol().description; // undefined
//全局 symbols
Symbol.for('foo').toString(); // "Symbol(foo)"
Symbol.for('foo').description; // "foo"
Function.prototype.toString() 现在返回精确字符,包括空格和注释
try-catch catch 的参数可省略
ES11
1.私有属性 #age #weight
2.promise.allSettled([]) 返回所有promise的状态和数组
3.matchAll 获取所有的匹配到的iteratoer数组,可以用扩展运算符或者for of
4.Bight 大整型 只对整型int有效 Bight只能和Bight进行运算
5.globalThis 全局对象
String.prototype.matchAll 返回一个包含所有匹配正则表达式及分组捕获结果的迭代器。
var regexp = /t(e)(st(\d?))/g
var str = 'test1test2'
str.match(regexp) // ['test1', 'test2']
str.matchAll(regexp) // RegExpStringIterator {}
[...str.matchAll(regexp)] // [ ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4], ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4] ]
动态 import()
const modelpath = '/demo'
import(`@/pages${modelpath}`).then(module => {}).catch(err => {})
import.metaimport.meta会返回一个对象,有一个url属性,返回当前模块的url路径,只能在模块内部使用。export * as XX from 'module'和import * as XX from 'module'BigInt现在的基本数据类型(值类型)不止5种(ES6之后是六种)了哦!加上BigInt一共有七种基本数据类型,分别是:String、Number、Boolean、Null、Undefined、Symbol、BigIntBigInt可以表示任意大的整数。可以用在一个整数字面量后面加n的方式定义一个BigInt,如:10n,或者调用函数BigInt()。globalThis指向全局对象,浏览器下指向window- 可选链操作符(?.)
info.animal?.reptile?.tortoise - 空值合并操作符(??) 当左侧的操作数为
null或者undefined时,返回其右侧操作数,否则返回左侧操作数。 与逻辑或操作符(||)不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。
const foo = null ?? 'default string';
console.log(foo); // "default string"
const baz = 0 ?? 42;
console.log(baz); // 0
ES12
0. `String.prototype.replaceAll` `replaceAll` 返回一个全新的字符串,所有符合匹配规则的字符都将被替换掉,替换规则可以是字符串或者正则表达式。
let string = 'I like 前端,I like 前端公虾米' console.log(string.replace(/like/g,'love')) // 'I love 前端,I love 前端公虾米' console.log(string.replaceAll('like','love')) // 'I love 前端,I love 前端公虾米'
> 需要注意的是,`replaceAll` 在使用正则表达式的时候,如果非全局匹配(`/g`),则 `replaceAll()` 会抛出一个异常
console.log(string.replaceAll(/like/,'love')) // TypeError
2. `WeakRefs` 当我们通过(`const、let、var`)创建一个变量时,垃圾收集器 `GC` 将永远不会从内存中删除该变量,只要它的引用仍然存在可访问。`WeakRef` 对象包含对对象的弱引用。对对象的弱引用是不会阻止垃圾收集器 `GC` 恢复该对象的引用,则 `GC` 可以在任何时候删除它。 `WeakRefs` 在很多情况下都很有用,比如使用 `Map` 对象来实现具有很多需要大量内存的键值缓存,在这种情况下最方便的就是尽快释放键值对占用的内存。 目前,可以通过 `WeakMap()` 或者 `WeakSet()` 来使用 `WeakRefs`。
2. 逻辑运算符和赋值表达式 表达式 `a op= b` 等同于 `a = a op (a = b)`
a ||= b //等价于 a = a || (a = b) // 当LHS值不存在时,将RHS变量赋值给LHS a &&= b //等价于 a = a && (a = b) // 当LHS值存在时,将RHS变量赋值给LHS a ??= b //等价于 a = a ?? (a = b) // 当LHS值为null或者undefined时,将RHS变量赋值给LHS
0. 数字分隔符号 数字分隔符,可以在数字之间创建可视化分隔符,通过 `_` 下划线来分割数字,使数字更具可读性
const money = 1_000_000_000 //等价于 const money = 1000000000 const totalFee = 1000.12_34 //等价于 const totalFee = 1000.1234 // 该新特性同样支持在八进制数中使用 const number = 0o123_456 //等价于 const number = 0o123456
\