溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

ES11的新特性有哪些

發(fā)布時間:2020-10-26 16:25:32 來源:億速云 閱讀:120 作者:Leah 欄目:開發(fā)技術(shù)

本篇文章給大家分享的是有關(guān)ES11的新特性有哪些,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

特性搶先知:

  • 私有變量
  • Promise.allSettled
  • BigInt 全新的數(shù)據(jù)類型
  • Nullish Coalescing Operator 空位合并運算符
  • Optional Chaining Operator 可選鏈運算符
  • Dynamic Import 動態(tài)導入
  • String.prototype.matchAll 新增matchAll
  • globalThis 新增全局對象
  • Module Namespace Exports 導入特定命名空間

私有變量

嚴格限制一些用于內(nèi)部使用的Class變量,只需要在變量前 添加# ,就可以使其成為私有變量,并且無法在class外部直接訪問

下面我們以一個簡單的

class Hero {
  #aggressivity = 0
  constructor (aggressivity){
   this.#aggressivity = aggressivity
  }
  getHurt(){
   return this.#aggressivity
  }
  setAggressivity(aggressivity){
   this.#aggressivity = aggressivity
  }
}

const shooter = new Hero(100)
let hurt = shooter.getHurt()
console.log(hurt) //100
console.log(shooter.#aggressivity) //Error : Uncaught SyntaxError: Private field '#aggressivity' must be declared in an enclosing class

上面代碼我們會發(fā)現(xiàn),無法直接進行訪問#aggressivity,將拋出異常

只能通過class里進行訪問,可通過統(tǒng)一class的公共方法進行統(tǒng)一修改

假設(shè)目前射手攜帶了 狂暴 技能,提升了 10%傷害 ,我們可以通過setAggressivity來修改攻擊力

ES11的新特性有哪些

let aggressivity = parseInt(hurt * 1.1)
shooter.setAggressivity(aggressivity)
console.log(shooter.getHurt()) // 110

Promise.allSettled

談及這個新特性之前,我們先簡單回顧下 Promise.all 以及 Promise.race ,推測下為什么需要 Promise.allSettled 這個新特性

Promise.all:可以將多個Promise實例包裝成一個新的Promise實例。同時,成功和失敗的返回值是不同的,成功的時候返回的是一個結(jié)果數(shù)組,而失敗的時候則返回最先被reject失敗狀態(tài)的值

let p1 = new Promise((resolve, reject) => {
 resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
 resolve('success')
})

let p3 = Promse.reject('失敗')

Promise.all([p1, p2]).then((result) => {
 console.log(result) //['成功了', 'success']
}).catch((error) => {
 console.log(error)
})

Promise.all([p1,p3,p2]).then((result) => {
 console.log(result)
}).catch((error) => {
 console.log(error) // 失敗了,打出 '失敗'
})

Promise.race:返回一個promise,一旦某個Promise觸發(fā)resolve或者reject,就直接返回該promise結(jié)果狀態(tài)

const promise1 = new Promise((resolve, reject) => {
 setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
 setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
 console.log(value);
});
//輸出 "two" 因為promise2返回結(jié)果比promise1快

有時候我們可能需要知道所有的結(jié)果做一些操作,并不關(guān)心其執(zhí)行結(jié)果是否成功,在沒有Promise.allSettled之前,我們需要自己實現(xiàn),可通過如下 實現(xiàn)Promise.allSettled

let allSettled = (funcArr) => {
 return new Promise((resolve) => {
  let sttled = 0
  let result = []
  for(let index = 0;index<funcArr.length;index++){
   const element = funcArr[index]
   element
   .then(res => { 
    result[index] = {
     status: 'fulfilled',
     value: res
    }
   })
   .catch(err => { 
    result[index] = {
     status: 'rejected',
     reason: err
    }
   })
   .finally(() => { ++sttled === funcArr.length && resolve(result) })
  }
 })
}

//使用
const promises = [
  Promise.reject('c'),
  Promise.resolve('a'),
  Promise.resolve('b'),
];

allSettled(promises).then(res => {
  console.log(res)
})

// 打印結(jié)果
// [{"status":"rejected","reason":"c"},
// {"status":"fulfilled","value":"a"},
// {"status":"fulfilled","value":"b"}]

而Promise.allSettled新特性出來后,我們可以直接使用而不需要單獨去實現(xiàn)了

const promises = [
  Promise.reject('c'),
  Promise.resolve('a'),
  Promise.resolve('b'),
];
Promise.allSettled(promises).then(res =>{
 console.log(res)
})
// 打印結(jié)果
// [{"status":"rejected","reason":"c"},
// {"status":"fulfilled","value":"a"},
// {"status":"fulfilled","value":"b"}]

返回結(jié)果里會將返回一個數(shù)組,包含了所有成功與失敗的結(jié)果,數(shù)組每項為對象,均含有 status 屬性,對應(yīng)fulfilled和rejected。

當狀態(tài)為 fulfilled 時,代表著成功,包含一個 value ,代表著成功的結(jié)果

當狀態(tài)為 rejected 時,代表著失敗,包含一個 reason ,代表著失敗的原因

BigInt

JS中缺少顯式整數(shù)類型常常令人困惑。許多編程語言支持多種數(shù)字類型,如浮點型、雙精度型、整數(shù)型和雙精度型,但JS卻不是這樣。在JS中,按照IEEE 754-2008標準的定義,所有數(shù)字都以雙精度 64位浮點格式 表示。

在此標準下,無法精確表示的非常大的整數(shù)將自動四舍五入。確切地說,JS 中的Number類型只能安全地表示-9007199254740991 (-(2^53-1)) 和9007199254740991(2^53-1)之間的整數(shù),任何超出此范圍的整數(shù)值都可能失去精度。

console.log(9999999999999999);  //10000000000000000

JS 提供 Number.MAX_SAFE_INTEGER 常量來表示 最大安全整數(shù), Number.MIN_SAFE_INTEGER 常量表示最小安全整數(shù):

// 注意最后一位的數(shù)字
const A = Number.MAX_SAFE_INTEGER + 1
const B = Number.MAX_SAFE_INTEGER + 2

console.log(Number.MAX_SAFE_INTEGER) //9007199254740991
console.log(A) //9007199254740992
console.log(B) //9007199254740992

console.log(A === B) //true

當數(shù)據(jù)超出范圍就會失去精度,達不到我們預(yù)期的結(jié)果。

BigInt橫空出世,可以在標準JS中執(zhí)行對大整數(shù)的算術(shù)運算,不必擔心精度損失風險

創(chuàng)建BigInt數(shù)據(jù)類型的方式非常簡單,在整數(shù)后面追加 n 即可,或者 通過BigInt()進行創(chuàng)建實例

const bigint = 999999999999999999n
const bigintByMethod = BigInt('999999999999999999')
console.log(bigint) //999999999999999999n
console.log(bigintByMethod) //999999999999999999n
console.log(bigint === bigintByMethod) //true

//布爾值
console.log(BigInt(true)) //1n
console.log(BigInt(false)) //0n

console.log(typeof bigint) //"bigint" 

BigInt 與 Number是兩種數(shù)據(jù)類型,無法進行運算,可以進行大小比較

console.log(88n == 88) //true
console.log(88n === 88) //false
console.log(88n+1) //Error =>Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

BigInt之間, 除了一元加號(+)運算符 外,其他均可用于BigInt

console.log(1n + 2n) //3n
console.log(1n - 2n) //-1n
console.log(+ 1n) //Uncaught TypeError: Cannot convert a BigInt value to a number
console.log(- 1n) //-1n
console.log(10n * 20n) //200n
console.log(23n%10n) //3n
console.log(20n/10n) //2n
......

需要注意的是, 除法運算符會自動向下舍入到最接近的整數(shù)

console.log(25n / 10n) //2n
console.log(29n / 10n) //2n

最后還有個注意點就是,Boolean類型和BigInt類型的轉(zhuǎn)換時,處理方式和Number類型,只要 不是0n,BigInt就被視為true

if (5n) {
  // 這里代碼塊將被執(zhí)行
}

if (0n) {
  // 這里代碼塊不會執(zhí)行
}

Nullish Coalescing Operator 空位合并運算符

新增一個邏輯運算符&#63;&#63;,處理null和undefined,工作原理與邏輯or( || )類似,但是與此相反

||如果為真即返回左側(cè)值,否則返回右側(cè)

0 || 5 // return 5
"" || 5 // return 5
"前端公蝦米" || 'V5' //return "前端公蝦米"

&#63;&#63;如果為null或者undefined,即返回右側(cè),否則返回左側(cè)

0 &#63;&#63; 5 //return 0
"" &#63;&#63; 5 //return ""
null &#63;&#63; 5 // return 5
undefined &#63;&#63; 5 // return 5
false &#63;&#63; 5 //return false
NaN &#63;&#63; 5 // return NaN

在使用該&#63;&#63;運算符時,需要注意的是

  • 不可與其他運算符組合使用,例如&&、||
  • 但若使用括號包裹則可以組合使用
"前端公蝦米" || undefined &#63;&#63; "Sneaker" //Uncaught SyntaxError: Unexpected token '&#63;&#63;'
"前端公蝦米" && undefined &#63;&#63; "Sneaker" //Uncaught SyntaxError: Unexpected token '&#63;&#63;'

("前端公蝦米" || undefined) &#63;&#63; "(&#3665;&#8226;&#768;&#12610;&#8226;&#769;)&#1608;&#10023;" //"前端公蝦米"
("前端公蝦米" && null) &#63;&#63; "一起學習" //"一起學習"

Optional Chaining Operator 可選鏈運算符

日常開發(fā)中,不少開發(fā)者會碰到Cannot read property XXX of undefined,拋出無法從未定義的數(shù)據(jù)中讀取某個字段

可選鏈運算符在查找嵌套對象時,找到鏈中的第一個 undefined 或者 null 后會立即終止,并返回 undefined ,而不會不斷向下查找而導致拋錯

const obj = {
 foo: {
  bar: {
   baz: 42,
  },
 },
}
console.log(obj.fo.bar.baz) //Uncaught TypeError: Cannot read property 'bar' of undefined

在諸如此類的對象里,我們通常進行數(shù)據(jù)安全檢查來訪問嵌套對象,否則將拋錯
if(obj&&obj.foo&&obj.foo.bar){
 console.log(obj.foo.bar.baz) // 42
}

在可選鏈運算符可使用的現(xiàn)在,我們只需這樣進行屬性的讀取

console.log(obj&#63;.foo&#63;.bar&#63;.baz) //42
      
console.log(obj.foo.bar&#63;.baz) //42

Dynamic Import 動態(tài)導入

在標準的import導入中,是靜態(tài)導入的,所有被導入的模塊是在加載時就被編譯的,無法按需編譯。當我們需要條件導入的時候,都只能使用 require() .

但現(xiàn)在,我們有辦法改善此類情況了,因為動態(tài)導入可以有效的減少未使用代碼的編譯,可以提高首屏加載速度,按需加載。

那么,為什么我們需要動態(tài)導入呢?

  • 靜態(tài)導入消耗加載時間,很多模塊并非首屏需要渲染
  • 靜態(tài)導入會在導入時消耗大量內(nèi)存
  • 可能會存在有些模塊在加載時不存在
  • 減少一些有條件依賴的副作用
//通用導入方式
import("/module/sneaker/test.js")
.then(module => {
 //模塊相關(guān)操作
})

//await
const getModule = await import("/module/sneaker/test.js")

//通過async await
const getUserInfo = async (hasLogin) => {
 if(!hasLogin){
 const user = await import("/module/sneaker/user.js")
  user.getInfo()
 }
}

matchAll

基于String原型上的一個新方法,允許我們匹配一個字符串和一個正則表達式,返回值是所有匹配結(jié)果的迭代器。

可以通過 for...of 遍歷或者 操作符... 、 Array.from 將結(jié)果迭代器轉(zhuǎn)換成數(shù)組

const string = 'Hello Sneaker,Where is the library&#63;'
const regex = /[A-W]/g
const matches = string.matchAll(regex)

console.log(...matches)
//["H", index: 0, input: "Hello Sneaker,Where is the library&#63;", groups: undefined] 
//["S", index: 6, input: "Hello Sneaker,Where is the library&#63;", groups: undefined] 
//["W", index: 14, input: "Hello Sneaker,Where is the library&#63;", groups: undefined] 

globalThis

這是為了提供一種訪問全局對象的標準方法。

在瀏覽器中,我們可以使用 window/self/frames 來訪問全局對象,但對于Web Workers只能使用 self ,Node中又完全不同,需要使用 global

globalThis 成為標準之前,獲取全局對象我們可能需要這么做

const globalObj = (()=>{
 if(self) return self
 if(window) return window
 if(global) return global
 throw new Error('Sorry!No global obj found')
})
//Browser 
globalThis === window //true

//Webworker
globalThis === self //true

//Node
globalThis === global //true

從此實現(xiàn)全局對象的大一統(tǒng)!

Module Namespace Exports 導入特定命名空間

export * as ns from './module

//等同于
import * as ns from './module'
export {ns}

導入特定命名空間實則并沒有導入模塊,只是對模塊進行轉(zhuǎn)發(fā),導致在此模塊中不可直接使用此模塊

以上就是ES11的新特性有哪些,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI