# 前言声明
# ES7
# includes
- 在 ES7 之前,如果我们想判断一个数组中是否包含某个元素,需要通过 indexOf 获取结果,并且判断是否为 -1。
- 在 ES7 中,我们可以通过 includes 来判断一个数组中是否包含一个指定的元素,根据情况,如果包含则返回 true,否则返回 false。
| const friends = ['伊莉雅', '樱岛麻衣', '入间同学', '薇尔莉特', NaN] |
| |
| |
| [1, 2, 3, +0].indexOf(-0) |
| [1, 2, 3, +0].includes(-0) |
| |
| |
| friends.indexOf('樱岛麻衣') |
| friends.indexOf('saber') |
| |
| friends.includes('伊莉雅') |
| friends.includes('saber') |
| |
| |
| const arr = [[1, 2], 3] |
| arr.includes([1, 2]); |
| arr.indexOf([1, 2]); |
| const friends = ['伊莉雅', '樱岛麻衣', '入间同学', '薇尔莉特', NaN] |
| |
| |
| friends.indexOf(NaN) |
| friends.includes(NaN) |
| |
| |
| friends.includes('樱岛麻衣', 2) |
# 指数运算符
- 在 ES7 之前,计算数字的乘方需要通过 Math.pow 方法来完成。
- 在 ES7 中,增加了 ** 运算符,可以对数字来计算乘方
| const result1 = Math.pow(2, 5) |
| const result2 = 2 ** 5 |
| |
| console.log(result1) |
| console.log(result2) |
# ES8
# Object.values
Object.values()
返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。
| const lain = { |
| name: 'lain', |
| age: 16 |
| } |
| |
| Object.values(lain) |
| |
| |
| ['樱岛麻衣', '薇尔莉特', '伊莉雅']) |
| |
| |
| Object.values('樱岛麻衣是我老婆') |
# Object.entries
Object.entries()
返回一个数组,其元素是与直接在 object
上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。
| const lain = { |
| name: 'lain', |
| age: 16 |
| } |
| |
| |
| Object.entries(lain) |
| |
| |
| Object.entries(['樱岛麻衣', '薇尔莉特', '伊莉雅']) |
| |
| |
| Object.entries('樱岛麻衣') |
# padStart
padStart()
方法用另一个字符串填充当前字符串 (如果需要的话,会重复多次),以便产生的字符串达到给定的长度。从当前字符串的左侧开始填充。
- 语法:
str.padStart(targetLength [, padString])
- 参数:
targetLength: 当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
padString 可选 填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的默认值为 " "(U+0020)。
- 返回值:
在原字符串开头填充指定的填充字符串直到目标长度所形成的新字符串。
| const str = '樱岛麻衣' |
| str.padStart(8) |
| str.padStart(8, '-') |
# padEnd
padEnd()
方法会用一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充。
- 语法:
str.padEnd(targetLength [, padString])
- 参数:
targetLength:
当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
padString 可选 填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的缺省值为 " "(U+0020)。
- 返回值:在原字符串末尾填充指定的填充字符串直到目标长度所形成的新字符串。
| const str = '樱岛麻衣' |
| |
| str.padEnd(1) |
| str.padEnd(10) |
| str.padEnd(10, "*") |
| str.padEnd(8, "-") |
# Demo
| const identityCard = '421126200006132333' |
| const lastIdentityCard = identityCard.slice(-4) |
| lastIdentityCard.padStart(identityCard.length, '*') |
# ES10
# flat
flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
- 语法:
var newArray = arr.flat([depth])
- 参数:
depth 可选
指定要提取嵌套数组的结构深度,默认值为 1
- 返回值:一个包含将数组与子数组中所有元素的新数组。
| |
| const arr = [1, 2, 3, [4, 5], [6, 7, [8, 9], [10, [11, 12]]]] |
| |
| |
| arr.flat() |
| |
| |
| arr.flat(2) |
| |
| |
| arr.flat(Infinity) |
# flagMap
-
flatMap()
方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,但 flatMap
通常在合并成一种方法的效率稍微高一些。
-
语法: var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) { // return element for new_array }[, thisArg])
-
参数:
-
callback
可以生成一个新数组中的元素的函数,可以传入三个参数:
-
currentValue
当前正在数组中处理的元素
-
index 可选
可选的。数组中正在处理的当前元素的索引。
-
array 可选
可选的。被调用的 map
数组
-
thisArg 可选
可选的。执行 callback
函数时 使用的 this
值。
-
flatMap 方法与 map 方法和深度 depth 为 1 的 flat 几乎相同.
| const characters = ['薇尔莉特 小鸟游六花','稚名真白 土间埋'] |
| |
| |
| const words1 = characters.map(item => item.split(' ')) |
| console.log(words1) |
| |
| |
| const words2 = characters.flatMap(item => item.split(' ')) |
| console.log(words2) |
# Object.fromEntries
-
Object.fromEntries()
方法把键值对列表转换为一个对象。、
- 语法:
Object.fromEntries(iterable)
- 参数:
iterable
类似 Array
、 Map
或者其它实现了可迭代协议的可迭代对象。
- 返回值:一个由该迭代对象条目提供对应属性的新对象。
Object.fromEntries()
方法接收一个键值对的列表参数,并返回一个带有这些键值对的新对象。这个迭代参数应该是一个能够实现 @@iterator
方法的的对象,返回一个迭代器对象。它生成一个具有两个元素的类数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。
Object.fromEntries()
执行与 Object.entries
互逆的操作。
| const entries = new Map([ |
| ['lain', 16], |
| ['saber', 17] |
| ]) |
| console.log(entries) |
| |
| const fromEntries = Object.fromEntries(entries) |
| console.log(fromEntries) |
# Demo
| const queryString = 'name=saber&age=16' |
| const queryParams = new URLSearchParams(queryString) |
| console.log(queryParams) |
| |
| for (const param of queryParams) { |
| console.log(param) |
| } |
| |
| |
| const paramObj = Object.fromEntries(queryParams) |
| console.log(paramObj) |
# trim()
# trimStart()
trimStart()
方法从字符串的开头删除空格。 trimLeft()
是此方法的别名。
- 返回值:一个新字符串,表示从其开头(左端)除去空格的调用字符串。
trimStart()
/ trimLeft()
方法移除原字符串左端的连续空白符并返回一个新字符串,并不会直接修改原字符串本身。
- 别名:为了与
String.prototype.padStart
等函数保持一致,标准方法名称为 trimStart
。 但是,出于 Web 兼容性原因, trimLeft
仍然是 trimStart
的别名。在某些引擎中,这意味着: String.prototype.trimLeft.name === "trimStart"
| const str = ' Hello World' |
| str.trimStart() |
# trimEnd
trimEnd()
方法从一个字符串的末端移除空白字符。trimRight () 是这个方法的别名。
- 返回值:一个新字符串,表示从调用字串的末(右)端除去空白。
trimEnd()
/ trimRight()
方法移除原字符串右端的连续空白符并返回, trimEnd()
/ trimRight()
方法并不会直接修改原字符串本身。
- 别名:为了与
String.prototype.padEnd
等函数保持一致,标准方法名称为 trimEnd
。 但是,出于 Web 兼容性原因, trimRight
仍然是 trimEnd
的别名。 在某些引擎中,这意味着: String.prototype.trimRight.name === "trimEnd";
| const str = 'Hello World ' |
| str.trimEnd() |
# description
description
是一个只读属性,它会返回 Symbol
对象的可选描述的字符串。
- 语法:
Symbol('myDescription').description;Symbol.iterator.description;Symbol.for('foo').description;
-
Symbol
对象可以通过一个可选的描述创建,可用于调试,但不能用于访问 symbol 本身。
| Symbol('lain').description |
| |
| Symbol('').description |
| |
| Symbol().description |
| |
| Symbol([1, 2, '3']).description |
| |
| Symbol({name: 'lain'}).description |
# ES11
# BigInt
-
BigInt
是一种内置对象,它提供了一种方法来表示大于 253 - 1
的整数。这原本是 Javascript 中可以用 Number
表示的最大数字。 BigInt
可以表示任意大的整数。
- 可以用在一个整数字面量后面加
n
的方式定义一个 BigInt
,如: 10n
,或者调用函数 BigInt()
。
| const bigInt = BigInt(10) |
| |
| console.log(typeof bigInt) |
| console.log(bigInt + 10n) |
| |
| const num1 = 100 |
| const num2 = 100 |
| console.log(bigInt + BigInt(num1)) |
| console.log(bigInt + BigInt(num2)) |
| const bigInt = BigInt(10) |
| |
| |
| const smallNum = Number(bigInt) |
| console.log(smallNum) |
# Nullish coalescing operator
- 空值合并操作符(
??
)是一个逻辑操作符,当左侧的操作数为 null
或者 undefined
时,返回其右侧操作数,否则返回左侧操作数。
- 与逻辑或操作符(
||
)不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 ||
来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如, ''
或 0
)时。见下面的例子。
| const nullValue = null; |
| const emptyText = ""; |
| const someNumber = 233; |
| |
| const valA = nullValue ?? "default valA" |
| const valB = emptyText ?? "default valB" |
| const valC = someNumber ?? 0 |
| const valD = null ?? 'null value' |
| const valE = undefined ?? 'undefined value' |
# Optional Chaining
- 可选链操作符 (
?.
) 允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。 ?.
操作符的功能类似于 .
链式操作符,不同之处在于,在引用为空 (nullish ) ( null
或者 undefined
) 的情况下不会引起错误,该表达式短路返回值是 undefined
。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined
。
- 当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。
| const lain = { |
| name: 'lain', |
| } |
| |
| console.log(lain.friend?.name) |
# globalThis
- 全局属性
globalThis
包含全局的 this
值,类似于全局对象(global object)
# ES12
# FinalizationRegistry
-
FinalizationRegistry
对象可以让你在对象被垃圾回收时请求一个回调。
-
FinalizationRegistry
提供了这样的一种方法:当一个在注册表中注册的对象被回收时,请求在某个时间点上调用一个清理回调。(清理回调有时被称为 finalizer )。
-
GC (Garbage Collection) 会不定时回收, 并不是立即销毁就回收的。
| const finalRegistry = new FinalizationRegistry((heldValue ) => { |
| console.log(`注册在finalRegistry中的 ${heldValue} 对象被销毁了`) |
| }) |
| |
| let lain = { |
| name: 'lain' |
| } |
| let saber = { |
| name: 'saber' |
| } |
| |
| finalRegistry.register(lain, 'lain') |
| finalRegistry.register(saber, 'saber') |
| |
| console.log(finalRegistry) |
| |
| lain = null |
| |
| saber = null |
# WeakRef
WeakRef 对象允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被 GC 回收
WeakRef.prototype.deref()
返回当前实例的 WeakRef 对象所绑定的 target 对象,如果该 target 对象已被 GC 回收则返回 undefined
| const finalRegistry = new FinalizationRegistry((heldValue ) => { |
| console.log(`注册在finalRegistry中的 ${heldValue} 对象被销毁了`) |
| }) |
| |
| let lain = { |
| name: 'lain' |
| } |
| let newLain = new WeakRef(lain) |
| |
| |
| finalRegistry.register(lain, 'lain') |
| finalRegistry.register(newLain, 'newLain') |
| |
| console.log(finalRegistry) |
| |
| lain = null |
| |
| setTimeout(() => { |
| console.log(newLain.deref()?.name) |
| }, 10000) |
# logical-assign-operator
# ||=
- 逻辑或赋值(
x ||= y
)运算仅在 x
为虚值时赋值。
| const example = { |
| a: 1, |
| b: 0, |
| c: '', |
| d: null, |
| e: undefined |
| } |
| |
| example.a ||= 'default value' |
| example.b ||= 'default value' |
| example.c ||= 'default value' |
| example.d ||= 'default value' |
| example.e ||= 'default value' |
# &&=
- 逻辑和赋值 (x &&= y) 操作符只在 x 为真时才赋值。
- 空值合并运算符从左至右求值,其使用以下规则测试是否可能进行语法短路求值:
(结果非 null 或 undefined 的表达式) ?? expr
被短路求值为左侧表达式,当左侧证明为既非 null
也非 undefined
.
| const example = { |
| a: 1, |
| b: 0, |
| c: '', |
| d: null, |
| e: undefined |
| } |
| |
| example.a &&= 'default value' |
| example.b &&= 'default value' |
| example.c &&= 'default value' |
| example.d &&= 'default value' |
| example.e &&= 'default value' |
# ??=
- 逻辑空赋值运算符 (
x ??= y
) 仅在 x
是 nullish ( null
或 undefined
) 时对其赋值。
| const example = { |
| a: 1, |
| b: 0, |
| c: '', |
| d: null, |
| e: undefined |
| } |
| |
| example.a ??= 'default value' |
| example.b ??= 'default value' |
| example.c ??= 'default value' |
| example.d ??= 'default value' |
| example.e ??= 'default value' |
# numeric separator
| const num = 1_000_000 |
| console.log(num) |
# replaceAll
| ### const str = 'Hello World' |
| |
| console.log(str.replaceAll('o', 'a')) |
| |
| console.log(str) |