五個最令人興奮的 ES13 功能
ES13 (ECMAScript 2022) 已經發布很久了,并且更新了許多有用的功能。
在這篇文章中,我想與大家分享 5 種我最喜歡的技術,這些技術是我已經開始在工作中實施的。
1. 頂級wait
wait 是我最喜歡的功能,因為它使我的代碼顯得更加優雅。確實,不再有回調地獄的負擔。
// Old Style
const getUserInfoOld = () => {
return fetch('/getUserId')
.then((userId) => {
return fetch('/getUserInfo', { body: JSON.stringify({ userId }) })
.then((userInfo) => {
return userInfo
})
})
}
// await Style
const getUserInfo = async () => {
const userId = await fetch('/getUserId')
const userInfo = await fetch('/getUserInfo', {
body: JSON.stringify({ userId })
})
return userInfo
}
“async”函數并不是唯一可以使用“await”的地方;你甚至可以這樣使用它,這真是太神奇了。
const mockUserInfo = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
userName: 'fatfish'
})
}, 1000)
})
}
const userInfo = await mockUserInfo()
// Can we print out { userName: 'fatfish' } please?
console.log(userInfo)
這個功能非常棒,可以讓我們做很多以前做不到的事情。
1.動態加載模塊
const enStrings = await import(`/i18n/en`)
2.初始化數據庫
const connection = await connectDB()
3. 有條件渲染模塊
const showBlackTheme = window.location.search.includes('theme=black')
if (showBlackTheme) {
await import('/theme/black.js')
} else {
await import('/theme/white.js')
}
2. Object.hasOwn
我們經常需要知道對象上是否存在某個屬性。怎么做?
“in”或“obj.hasOwnProperty”是用于此目的的兩種最常用的方法。
但它們都有一些缺陷,讓我們來看看。
“in”運算符
如果指定的屬性位于指定的對象或其原型鏈中,則 in 運算符返回 true。
const Person = function (age) {
this.age = age
}
Person.prototype.name = 'fatfish'
const p1 = new Person(24)
console.log('age' in p1) // true
console.log('name' in p1) // true pay attention here
obj.hasOwnProperty
hasOwnProperty 方法返回一個布爾值,指示對象是否將指定屬性作為其自己的屬性(而不是繼承它)。
使用上面相同的例子
const Person = function (age) {
this.age = age
}
Person.prototype.name = 'fatfish'
const p1 = new Person(24)
console.log(p1.hasOwnProperty('age')) // true
console.log(p1.hasOwnProperty('name')) // fasle pay attention here
也許“obj.hasOwnProperty”已經可以過濾掉原型鏈上的屬性,但在某些情況下,它并不安全,會導致程序失敗。
Object.create(null).hasOwnProperty('name')
// Uncaught TypeError: Object.create(...).hasOwnProperty is not a function
Object.hasOwn
不用擔心,我們可以使用“Object.hasOwn”來規避這兩個問題,這比“obj.hasOwnProperty”方法更方便、更安全。
let object = { age: 24 }
Object.hasOwn(object, 'age') // true
let object2 = Object.create({ age: 24 })
Object.hasOwn(object2, 'age') // false The 'age' attribute exists on the prototype
let object3 = Object.create(null)
Object.hasOwn(object3, 'age') // false an object that does not inherit from "Object.prototype"
3. 數組“.at()”方法
我們應該如何從數組的末尾開始獲取其中的元素呢?
是的,我們需要以“array.length — 1”作為下標來讀取。
const array = [ 1, 2, 3, 4, 5 ]
const lastEle = array[ array.length - 1 ] // 5
// You can't read like that
const lastEle = array[ - 1 ] // undefined
還有其他辦法嗎?
ES2022提供了一個名為at的數組方法,這可能是一個很小的改變,但是可以大大提高代碼的可讀性。
at 方法可以取正數或負數,這將決定它是從數組的頭部還是尾部開始讀取元素。
const array = [ 1, 2, 3, 4, 5 ]
const lastEle = array.at(-1) // 5
const firstEle = array.at(0) // 1
4. Error cause
在ES2022規范中,new Error()可以指定其錯誤的原因。
const readFiles = (filePaths) => {
return filePaths.map(
(filePath) => {
try {
// ···
} catch (error) {
throw new Error(
`${filePath} erroe`,
{cause: error}
)
}
})
}
有時,代碼塊的錯誤需要根據其原因進行不同的處理,但錯誤的原因相對相似,因此,能夠為它們分配錯誤名稱是很棒的。
5. 私有槽位及方法
過去,我們使用“_”來表示私有屬性,但它并不安全,仍然可能被外部修改。
class Person {
constructor (name) {
this._money = 1
this.name = name
}
get money () {
return this._money
}
set money (money) {
this._money = money
}
showMoney () {
console.log(this._money)
}
}
const p1 = new Person('fatfish')
console.log(p1.money) // 1
console.log(p1._money) // 1
p1._money = 2 // Modify private property _money from outside
console.log(p1.money) // 2
console.log(p1._money) // 2
我們可以使用“#”來實現真正安全的私有屬性
class Person {
#money=1
constructor (name) {
this.name = name
}
get money () {
return this.#money
}
set money (money) {
this.#money = money
}
showMoney () {
console.log(this.#money)
}
}
const p1 = new Person('fatfish')
console.log(p1.money) // 1
// p1.#money = 2 // We cannot modify #money in this way
p1.money = 2
console.log(p1.money) // 2
console.log(p1.#money) // Uncaught SyntaxError: Private field '#money' must be declared in an enclosing class