博客 / 詳情

返回

原來ES7~12分別增加了這些屬性呀

ES6也稱為ES2015,於2015年發佈,此後每年都有新增一些屬性,分別命名為ES7~12,發佈的年份分別對應2016年到2021年

ES7

includes方法

數組中新增了includes方法,用來判斷數組中是否存在某一元素,在此之前進行這樣的判斷是使用indexOf判斷下標值,小於0時則代表不存在。

const list = ['alice', 'kiki', 'macus']

console.log(list.includes('alice'))
console.log(list.indexOf('alice'))

console.log(list.includes('hello'))
console.log(list.indexOf('hello'))

includes返回布爾值,indexOf返回數組的下標

指數運算

ES7增加了指數運算的操作符,兩個星號(**),在此之前通過 Math.pow 來計算

const num = 3
const sqrt = Math.pow(num, 4)
const result = num ** 4
console.log(sqrt, result)

以上都表示 num 的四次方,執行結果都為81

** 運算符通過babel編譯成es5的語法時,也是使用的 Math.pow

ES8

Object.values和Object.entries

Object.keys (ES6之前就有的屬性) 獲取對象的所有key值,Object.values獲取對象的所有value值,Object.entries會返回一個數組,數組中包含每一個key和value元素組成的數組

const obj = {
  name: 'alice',
  age: 18
}
const list = ['alice', 'kiki', 'macus']
const messsage = 'hello'

console.log(Object.keys(obj), Object.values(obj), Object.entries(obj))
console.log(Object.keys(list), Object.values(list), Object.entries(list))
console.log(Object.keys(messsage), Object.values(messsage), Object.entries(messsage))

分別獲取數組、對象和字符串的key、value和由key、value組成的數組

stringPadding

對字符串分別使用padStart和padEnd可以進行頭、尾填充,傳入填充後的字符串長度和填充內容

const message = "hello world"
const startMsg = message.padStart(15, '-')
const endMsg = message.padEnd(16, '*')
console.log(startMsg)
console.log(endMsg)


const nickName = '星辰'
const firstName = nickName.substr(0, 1)
const newName = firstName.padEnd(nickName.length, '*')
console.log(newName)

分別對字符串的頭尾進行了填充以及一個小案例

Trailing Commas

尾部逗號,允許函數在定義形參及傳遞參數的時候,最後一個參數後增加一個逗號(,)

function foo(a, b,){
  console.log(a, b,)
}
foo(1,2,)

function baz(m, n){
  console.log(m, n)
}
baz('m', 'n',)

在最後一個參數後增加逗號,也不會被認為是錯誤的寫法

getOwnPropertyDescriptors

用於獲取對象的所有屬性的描述

const obj = {
  name: 'alice',
  age: 18
}
console.log(Object.getOwnPropertyDescriptors(obj))

包含是否可枚舉(enumerable)、可修改(writable)、重新定義(configurable)及value值

其它
  • async和await,這部分放到後面的文章中詳細的記錄

ES9

所有屬性
  • iterators 迭代器,這部分放到後面的文章中詳細的記錄
  • spread operators,對象展開運算符,記錄在 你知道ES6中的這些屬性嗎 這篇文章中
  • promise finally,和promise一起放到後面的文章中詳細的記錄

ES10

flat和flatMap

flat這個函數是用來對數組降維的,只需要傳入需要降維的層級

const array = [1, 2, [3, 4], [[5, 6], [7, 8], [9]], [10], 11, 11, 11, [12, [13, [14]]]]
const num = array.flat(2)
console.log(num)

此時傳入降維的層次是2,所以四維數組的數據降了兩維,還有兩維

flatMap這個方法會先對數組遍歷,再進行降維操作,作用相當於map+flat

const list = ["macus mogan", "arish sira", "linda kiki"]
const result = list.flatMap(item => {
  const element = item.split(" ")
  console.log('每次拆分的元素:',element)
  return element
})
console.log(result)

此時遍歷出每組元素時候,通過空格切割成數組,flatMap會直接降維

Object.fromEntries

Object.fromEntries是將entries這樣的數組類型轉換成對象

const obj = {
  name: 'alice',
  age: 18
}
const arr = ['alice', 'kiki', 'macus']
const str = 'hello'
const objEntries = Object.entries(obj)
const arrEntries = Object.entries(arr)
const strEntries = Object.entries(str)

console.log(objEntries)
console.log(Object.fromEntries(objEntries))
console.log('--------------------------------------------------------------')
console.log(arrEntries)
console.log(Object.fromEntries(arrEntries))
console.log('--------------------------------------------------------------')
console.log(strEntries)
console.log(Object.fromEntries(strEntries))

分別將對象、數組、字符串變成entries後,再通過fromEntries轉為對象,fromEntries並不是反向的Object.entries操作,不會恢復數組或者字符串的類型

trimStart trimEnd

trim可以用於去除首尾空格,ES10又增加了trimStart trimEnd分別用於在字符串頭 尾部去除空格

const message = " hello world "
const messageLen = message.length
const trimMsg = message.trim()
const trimStartMsg = message.trimStart()
const trimEndMsg = message.trimEnd()

console.log(messageLen)
console.log(trimMsg, trimMsg.length)
console.log(trimStartMsg, trimStartMsg.length)
console.log(trimEndMsg, trimEndMsg.length)

通過字符串的長度可以判斷是否去除了首尾的空格

其它
  • Symbol的Desciptor屬性,記錄在 你知道ES6中的這些屬性嗎 這篇文章中
  • Optional catch binding,放到後面try catch 文章中一起記錄

ES11

bigInt

在此之前表示大數字可用 Number.MAX_SAFE_INTEGER,但這種表示方式如果要進行計算,是存在精度問題的,ES11增加了一種表示大數字的方式,在數字後面寫上字母n,如1234567890987654321n。

但這種方式進行運算,仍有一些規則

  1. 帶n的大數字是不可以與不帶n的小數字進行運算的

    • 可以將小數字後面直接加個n
    • 或者通過BigInt方法將小數字轉成大數字
  2. 將大數字通過轉成小數字可能存在精度丟失的問題
const num = Number.MAX_SAFE_INTEGER
console.log(num + 1)
console.log(num + 2)

const bigNum = 80082088208008208820n
console.log(bigNum + 10n)
console.log(bigNum + BigInt(10))
console.log(Number(bigNum))

以上MAX_SAFE_INTEGER運算 和 bigInt 轉Number就都出現了精度丟失的問題

Nullish Coalescing Operator

空值合併操作符(??),對數據進行布爾值的判斷,將null和undefined的數據判斷為false,就會取運算符後面的值,而或運算符(||)對於null、undefined、空字符串和0都判斷為false

const nullStr = null;
const undefinedStr = undefined;
const string = "";
const number = 0;
const user = {};

console.log(nullStr ?? "不存在的內容", nullStr || "不存在的內容");
console.log(undefinedStr ?? "不可識別的類型", undefinedStr || "不可識別的類型");
console.log(string ?? "空字符串", string || "空字符串");
console.log(number ?? "數字", number || "數字");
console.log(user ?? "空對象", user || "空對象");

兩者僅在空字符串和數字0的情況判斷會不一致

Optional Chining

可選鏈(?.)在對象中使用,對數據的存在/可讀取與否進行判斷,當它不為null和undefined時,才會往下操作。

const user = {
  name: 'alice',
  favorite: {
    sport: 'tennis'
  }
}
console.log(user?.favorite?.sport)
console.log(user && user.favorite && user.favorite.sport)
console.log(user?.info?.address)
console.log( user && user.info && user.info.address)

通過可選鏈與 && 操作符所實現的效果一致,但代碼更為簡潔

globalThis

javascript代碼可以運行在瀏覽器或者nodejs中,這兩個容器獲取全局對象的方式不相同,在瀏覽器中可以通過 window 或者 this,在node端需要通過global。es11中進行了統一,使用globalThis,無論在瀏覽器端或者node端都可以直接獲取全局對象。

console.log(globalThis)

瀏覽器中打印的是window對象,node端打印的是global對象

其它
  • for in 標準化,在es11之前,沒有規定for in 遍歷時的key需要取 key 還是 value,各瀏覽器都有自己的實現,es11指定標準,需使用key
  • Dynamic Import(動態導入),將記錄在es模塊化的文章中
  • Promise.allSettled,將記錄在promise的文章中
  • import meta,將記錄在es模塊化的文章中

ES12

FinalizationRegistry

用於對象被垃圾回收器(GC)回收的時候指定一個回調,通過 register 進行註冊

let user = {
  name: "alice",
};
const registry = new FinalizationRegistry((value) => {
  console.log("對象被銷燬了", value);
});
registry.register(user, 'user')
user = null

GC是不定時的檢測有沒有可回收的垃圾,所以當對象指向null時,不會馬上執行獲取回調的函數,不能在nodejs中測試,只能在瀏覽器中測試,因為在nodejs中執行完成會關閉該進程,瀏覽器運行時是一個進程,不會關閉。

WeakRef

直接將對象A賦值給對象B,他們共同指向一個內存地址0x100,因為此時是強引用,即使A指向null之後,0x100仍被B指向,所以0x100不會被銷燬。

如果希望A指向null之後,0x100被銷燬,那麼可以使用 weakRef 實現弱引用。

let user = { name: 'alice' }
let info = new WeakRef(user)

const registry = new FinalizationRegistry((value) => {
  console.log("對象被銷燬了", value);
});
registry.register(user, 'user')
registry.register(info, 'info')

user = null
console.log(info, info.deref())

通過new關鍵字創建弱引用,通過deref方法獲取數據,當引用的對象被回收後,弱引用生成的對象也就獲取不到了

logical assignment operators

賦值邏輯運算,相當於是邏輯運算後,再進行賦值的操作

  • ||= 邏輯或賦值運算,先或運算,再賦值
  • &&= 邏輯與賦值運算,先與運算,再賦值
  • ??= 邏輯空賦值運算,先空值判斷,再賦值
let num = 0
// num = num + 1 等同於下方寫法
num += 1
console.log(num)

let message = ''
// message = message || 'hello' 等同於下方寫法
message ||= 'hello'
console.log(message)

let user = {
  name: 'alice'
}
// user = user && user.name 等同於下方寫法
user &&= user.name
console.log(user)

let str = 0
// str = str ?? 'string' 等同於下方寫法
str ??= 'string'
console.log(str)

邏輯賦值運算 就像+= 和 +1之後再賦值一樣,是一種運算的語法糖

Numeric Separator

數字分隔符,較大的數字可以通過下劃線(_)進行分割,使代碼可讀性更強

const momeny = 100_200_300_400_500
console.log(momeny)

執行結果會去除下劃線,以十進制數據展示

replaceAll

replaceAll() 方法返回一個新字符串,新字符串所有滿足 pattern(第一個參數) 的部分都已被replacement(第二個參數) 替換。

const message = "hello world";

console.log(message.replace("l", "*"));
console.log(message.replaceAll("l", "*"));

replaceAll會替換所有符合條件的,而replace只會替換掉第一個

以上就是ES7-12包含的大部分屬性,關於js高級,還有很多需要開發者掌握的地方,可以看看我寫的其他博文,持續更新中~

user avatar duan_599e492b96365 頭像 taoguo 頭像
2 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.