ES11
Promise.allSettled
Promise.allSettled() 方法返回一个在所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise ,并带有一个对象数组,每个对象表示对应的 promise 结果。
const promises = [ ajax('/200接口'), ajax('/401接口') ];
Promise.allSettled(promises).then(results=>{
// 过滤出成功的请求
results.filter(item =>item.status === 'fulfilled');
过滤出失败的请求
results.filter(item=> item.status === 'rejected');
})
module新增
标准用法的 import 导入的模块是静态的,会使所有被导入的模块,在加载时就被编译(无法做到按需编译,降低首页加载速度)。有些场景中,你可能希望根据条件导入模块或者按需导入模块,这时你可以使用动态导入代替静态导入。
<body>
<button>login</button>
<script type="module">
let role1 = "管理员"
let role2 = "普通用户"
function login(){
return "普通用户"
}
async function render(role){
if(role===role1){
let res1 = await import("./1.js")
console.log(res1.default)
}else{
let res2 = await import("./2.js")
console.log(res2.default)
}
}
let obtn = document.querySelector("button")
obtn.onclick = function(){
let role = login()
render(role)
}
</script>
</body>
import.meta
import.meta 会返回一个对象,有一个 url 属性,返回当前模块的url路径,只能在模块内部使用。
<script type="module">
import obj from './1.js'
</script>
//1.js
console.log(import.meta)
export default {
}
export * as obj from 'module'
//1.js
export default {
name:'111111'
}
export function test1(){
}
//2.js
export default {
name:"22222"
}
export function test2(){
}
export * as obj1 from './1.js'
//html
<script type="module">
import * as obj from './2.js'
console.log(obj)
</script>
字符串的matchAll方法
matchAll() 方法返回一个包含所有匹配正则表达式的结果的迭代器。可以使用 for...of 遍历,或者使用 展开运算符(...) 或者 Array.from 转换为数组.
let str = `
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
`
let reg = /<li>(.*)<\/li>/g
console.log(str.match(reg))
//'<li>1111</li>', '<li>2222</li>', '<li>3333</li>', '<li>4444</li>'
let str = `
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
`
let reg = /<li>(.*)<\/li>/g
for(let i of str.matchAll(reg)){
console.log(i)
}
BigInt
JavaScript 能够准确表示的整数范围在-2^53到2^53之间(不含两个端点),超过这个范围,无法精确表示这个值,这使得 JavaScript 不适合进行科学和金融方面的精确计算。
9007199254740992 //9007199254740992
9007199254740993 //9007199254740992
Math.pow(2,53) === Math.pow(2,53)+1
为了与 Number 类型区别,BigInt 类型的数据必须添加后缀n
。
1234 // 普通整数
1234n // BigInt
// BigInt 的运算
1n + 2n // 3n
globalThis
globalThis 提供了一个标准的方式来获取不同环境下的全局 this 对象(也就是全局对象自身)。不像 window 或者 self这些属性,它确保可以在有无窗口的各种环境下正常工作。所以,你可以安心的使用 globalThis,不必担心它的运行环境。为便于记忆,你只需要记住,全局作用域中的 this 就是 globalThis。
//es6-shim
var getGlobal = function () {
// the only reliable means to get the global object is
// Function('return this')()
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') {
return self; }
if (typeof window !== 'undefined') {
return window; }
if (typeof global !== 'undefined') {
return global; }
throw new Error('unable to locate global object');
};
var globals = getGlobal();
if (!globals.Reflect) {
defineProperty(globals, ‘Reflect’, {
}, true);
}
空值合并运算符
空值合并运算符(??)是一个逻辑运算符。当左侧操作数为 null 或 undefined 时,其返回右侧的操作数。否则返回左侧的操作数。
let obj = {
name:"kerwin",
introduction:0
}
console.log(obj.introduction || "这个人很懒")
console.log(obj.introduction ?? "这个人很懒")
??和 || 的区别是什么呢?
他们两个最大的区别就是 ’ '和 0,??的左侧 为 ’ '或者为 0 的时候,依然会返回左侧的值;
|| 会对左侧的数据进行boolean类型转换,所以’ '和 0 会被转换成false,返回右侧的值
可选链操作符
可选链前面的值如果是null或undefined,则不再执行后面的,之前返回可选链前面的值
let obj = {
name:"xxx",
introduction:0,
// location:{
// city:"dalian"
// }
}
console.log(obj && obj.location && obj.location.city)
console.log(obj?.location?.city)
ES12
逻辑赋值操作符
let a = true
let b = false
//a &&= b //false
a ||= b ; //true
console.log(a)
let obj = {
name:"kerwin",
}
obj.introduction = obj.introduction??"很懒"
obj.introduction??="很懒"
数字分隔符
这个新特性是为了方便程序员看代码而出现的,如果数字比较大,那么看起来就不是那么一目了然
const num= 123456789;
分隔符不仅可以分割十进制,也可以分割二净值或者十六净值的数据,非常好用。
const number = 1_000_000_000_000;
const binary = 0b1010_0101_1111_1101;
const hex = 0xA1_B2_C3;
replaceAll
所有匹配都会被替代项替换。模式可以是字符串或正则表达式,而替换项可以是字符串或针对每次匹配执行的函数。并返回一个全新的字符串
const str =
"I wish to wish the wish you wish to wish, but if you wish the wish the witch wishes, I won't wish the wish you wish to wish. ";
const newStr = str.replaceAll("wish", "kerwin");
console.log(newStr);
Promise.any
只要参数实例有一个变成fulfilled
状态,包装实例就会变成fulfilled
状态;如果所有参数实例都变成rejected
状态,包装实例就会变成rejected
状态。
Promise.any()
跟Promise.race()
方法很像,只有一点不同,就是Promise.any()
不会因为某个 Promise 变成rejected
状态而结束,必须等到所有参数 Promise 变成rejected
状态才会结束。WeakRef
在一般情况下,对象的引用是强引用的,这意味着只要持有对象的引用,它就不会被垃圾回收。只有当该对象没有任何的强引用时,垃圾回收才会销毁该对象并且回收该对象所占的内存空间。
而 WeakRef
允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被垃圾回收。
let target = {
};
let wr = new WeakRef(target);
WeakRef 实例对象有一个deref()
方法,如果原始对象存在,该方法返回原始对象;如果原始对象已经被垃圾回收机制清除,该方法返回undefined
。
let target = {
};
let wr = new WeakRef(target);
let obj = wr.deref();
if (obj) {
// target 未被垃圾回收机制清除
// ...
}
let like = new WeakRef(document.getElementById("like"))
let mymap = new WeakMap()
mymap.set(like.deref(), {
click: 0
})
like.deref().onclick = function () {
let times = mymap.get(like.deref())
times.click++
}
setTimeout(() => {
document.body.removeChild(like.deref())
}, 2000)
FinalizationRegistry
清理器注册表功能 FinalizationRegistry,用来指定目标对象被垃圾回收机制清除以后,所要执行的回调函数。
let like = new WeakRef(document.getElementById("like"))
let mymap = new WeakMap()
mymap.set(like.deref(), {
click: 0
})
like.deref().onclick = function () {
let times = mymap.get(like.deref())
times.click++
}
setTimeout(() => {
// registry.register(document.getElementById("like"), mymap.get(like.deref()));
registry.register(like.deref(), mymap.get(like.deref()));
document.body.removeChild(like.deref())
}, 2000)
const registry = new FinalizationRegistry(data => {
// ....
console.log("被销毁了", data)
});
ES13新特性
私有属性和方法
class Cache{
#obj ={
}
get(key){
return this.#obj[key]
}
set(key,value){
this.#obj[key] =value
}
}
let cache = new Cache()
cache.set("name","xxx")
静态成员的私有属性和方法
class Cache{
static #count = 0;
static getCount(){
return this.#count
}
#obj ={
}
get(key){
return this.#obj[key]
}
set(key,value){
this.#obj[key] =value
}
}
let cache = new Cache()
cache.set("name","kerwin")
console.log(Cache.getCount())
静态代码块
一个类可以定义任意多的静态代码块,这些代码块会和穿插在它们之间的静态成员变量一起按照定义的顺序在类初始化的时候执行一次。我们还可以使用
super
关键字来访问父类的属性。
class Cache{
static obj = new Map()
static {
this.obj.set("name","kerwin")
this.obj.set("age",100)
}
static{
console.log(this.obj)
}
}
console.log(Cache.obj)
使用in来判断某个对象是否拥有某个私有属性
class Cache {
#obj = {
}
get(key) {
return this.#obj[key]
}
set(key, value) {
this.#obj[key] = value
}
hasObj(){
return #obj in this
}
}
let cache = new Cache()
console.log(cache.hasObj())
at函数来索引元素
let arr = ["tiechui","gangdan","xiaoming"]
console.log(arr[1])
console.log(arr[arr.length-1]) //变丑了
console.log(arr[arr.length-2]) //变丑了
console.log(arr.at(1))
console.log(arr.at(-1))
console.log(arr.at(-2))