您好,登錄后才能下訂單哦!
這篇文章主要介紹“JavaScript ECMAScript6所有新特性怎么用”,在日常操作中,相信很多人在JavaScript ECMAScript6所有新特性怎么用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JavaScript ECMAScript6所有新特性怎么用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
ES2015是改動最大的一個版本,基本上對ES2015之前的所有的內容都做了擴展,大體如下所示:
在ES6之前只有一種聲明變量的方式,就是使用var
關鍵字,在ES2015中新增了let
和const
關鍵字來聲明變量與常量,
代碼如下:
// 聲明變量 let v = 100 v = 200 // 聲明常量 const V = 200 // 修改常量 // V = 300 // 報錯
同時使用let
和const
關鍵字聲明的變量或者常量是具有塊級作用域的,
示例代碼如下:
{ var v = 100 } { let val = 200 } console.log(v) console.log(val) // 報錯 val is not defined
值得注意的是使用let
或者const
關鍵字聲明的變量不具有變量提升的特性,且存在暫時性死區的特性。
在ES2015中允許函數使用默認值,示例代碼如下:
// es2015之前 function foo(v) { v = v ? v : 100 return v } // es2015 function bar(v = 100) { return v }
值得注意的是如果有多個參數時,默認參數必須從后向前使用。
在ES2015中新增了箭頭函數,這是函數的一種簡寫形式,示例代碼如下:
function foo(v) { return v`` } // 箭頭函數寫法 const foo = (v) => { return v } // 簡寫形式 1 const foo = v => { // 只有一個參數可以省略括號 return v } // 簡寫形式 2 const foo = v => v // 語句中只有return時可以省略return和花括號
值得注意的是箭頭函數的this
是根據執行上下文決定的,內部并不會綁定this
。
使用箭頭函數時內部并不存在arguments對象,而是采用剩余參數的方式代替,
示例代碼如下:
const foo = (...args) => { // console.log(arguments) // ReferenceError: arguments is not defined console.log(args) // args 是一個數組 } foo(1, 2, 3, 4) // [ 1, 2, 3, 4 ]
在ES2015中為函數增加的要給name屬性,該屬性指向函數的名稱,
示例代碼如下:
function foo(v) { return v } const bar = v => v console.log(foo.name) // foo console.log(bar.name) // bar
在ES2015中對數值的擴展主要時為Math
和Number
兩個對象增加一些方法,以及二進制和八進制的表示方法。
在ES2015中使用0b
或者0B
表示二進制,使用0o
或者0O
表示八進制。
示例代碼如下:
console.log(0b111111111 === 511) // true console.log(0o777 === 511) // true
為Number擴展的屬性和方法如下:
屬性/方法名 | 描述 |
---|---|
Number.EPSILON | 數值最小精度 |
Number.MIN_SAFE_INTEGER | 最小安全數(-2^53 ) |
Number.MAX_SAFE_INTEGER | 最大安全數(2^53 ) |
Number.parseInt() | 把參數解析為整數并返回 |
Number.parseFloat() | 把參數解析為浮點數并返回 |
Number.isFinite() | 判斷是否為有限數值 |
Number.isNaN() | 判斷是否為NaN |
Number.isInteger() | 判斷是否為整數 |
Number.isSafeInteger() | 判斷數值是否在安全范圍內 |
為Math擴展的方法如下:
方法名 | 描述 |
---|---|
Math.trunc() | 返回數值整數部分 |
Math.sign() | 返回數值類型(正數1、負數-1、零0 ) |
ES2015引入模板字符串,使用反引號(`)定義,模板字符串會保留格式,且可以使用變量,
示例代碼如下:
// 使用 ` 定義模板字符串 let str = `一碗周` // 模板字符串可以保留格式 let str2 = `一 碗 周` // 模板字符串可以使用變量 const myName = '一碗周' let str3 = `author: ${myName}` // 使用 ${} 進行包裹
ES2015還為String和String的實例擴展了一些方法,如下:
方法名 | 描述 |
---|---|
String.fromCodePoint() | 用于從 Unicode 碼點返回對應字符 |
String.raw() | 返回一個斜杠都被轉義(即斜杠前面再加一個斜杠)的字符串,往往用于模板字符串的處理方法。 |
String.prototype.codePointAt() | 返回字符對應碼點(String.fromCodePoint()的逆操作) |
String.prototype.normalize() | 把字符的不同表示方法統一為同樣形式,返回新字符串(Unicode正規化) |
String.prototype.repeat() | 把字符串重復n次,返回處理后的字符串 |
String.prototype.includes() | 判斷是否存在指定字符串 |
String.prototype.startsWith() | 判斷字符串是否存在原始字符串的頭部 |
String.prototype.endsWith() | 判斷字符串是否存在原始字符串的尾部 |
在ES2015中提供了展開運算符,即...,在數組中使用可以將數組展開,并以逗號分隔,
示例代碼如下:
const arr = [1, 2, 3, 4, 5, 6] const newArr = [...arr] // 復制數組 console.log(Math.max.call(null, ...arr)) // 將數組中的每一項作為參數使用
除此之外,還為Array以及數組提供了一系列方法,來逐個介紹:
Array.from()
:將類數組對象或者可迭代對象創建為一個新的數組,示例代碼如下:
function foo() { return Array.from(arguments) // 將 arguments 轉換為數組 } console.log(foo(1, 2, 3, 4, 5, 6)) // [ 1, 2, 3, 4, 5, 6 ]
Array.of()
:創建一個具有可變數量參數的新數組實例,示例代碼如下:
Array.of(1) // [1] Array.of(true, 1, '一碗周') // [true, 1, '一碗周']
Array.prototype.copyWithin(),淺復制數組的一部分到同一數組中的另一個位置,并返回它,不會改變原數組的長度。
示例代碼如下:
const arr = [1, 2, 3, 4] // 從索引 2 開始,到結束 將內容復制到索引 0 的位置 arr.copyWithin(0, 2) // [ 3, 4, 3, 4 ]
Array.prototype.find()
,根據給定的回調函數,找到匹配的第一個元素,找不到返回undefined,示例代碼如下:
const arr = [1, 2, 3, 4] arr.find(item => item === 2) // 2(表示元素)、
Array.prototype.findIndex()
,根據給定的回調函數,找到匹配的第一個元素的索引,找不到返回-1,示例代碼如下:
const arr = [1, 2, 3, 4] arr.findIndex(item => item === 2) // 1 (表示索引)
Array.prototype.fill()
,將給定值填充數組,示例代碼如下:
const arr = [1, 2, 3, 4] // 將給定值填充索引1-3 arr.fill('一碗周', 1, 3) // [ 1, '一碗周', '一碗周', 4 ]
Array.prototype.keys()
,返回一個可迭代的對象,其內容為數組的key,示例代碼如下:
const arr = [1, true, '一碗周'] const keys = arr.keys() for (const i of keys) { console.log(i) // 遍歷結果 0 1 2 }
Array.prototype.values()
,返回一個可迭代的對象,其內容為數組的value,
示例代碼如下:
const arr = [1, true, '一碗周'] const values = arr.values() for (const i of values) { console.log(i) // 遍歷結果 1 true 一碗周 }
Array.prototype.entries()
,返回一個可迭代的對象,其內容是一個數組,索引0
為原數組的元素,1
為原數組該位置的值,
示例代碼如下:
const arr = [1, true, '一碗周'] const iterator = arr.entries() console.log(Array.from(iterator)) // [ [ 0, 1 ], [ 1, true ], [ 2, '一碗周' ] ]
ES2015中允許對象的屬性名和屬性值一致時可以只寫屬性名,
示例代碼如下:
const myName = '一碗周' const age = 18 const person = { myName, age } console.log(person) // { myName: '一碗周', age: 18 }
還有就是在定義對象時,允許使用[]包裹表達式作為屬性名,示例代碼如下:
const myName = '一碗周' const age = 18 const person = { myName, ['a' + 'g' + 'e']: age, } console.log(person) // { myName: '一碗周', age: 18 }
Object.is()
:用于比較兩個值是否相等,用于解決NaN ≠= NaN,+0 === -0的問題,
示例代碼如下:
console.log(NaN === NaN) // false console.log(+0 === -0) // true console.log(Object.is(NaN, NaN)) // true console.log(Object.is(+0, -0)) // false
Object.assign()
:將所有可枚舉屬性的值從一個或多個源對象復制到目標對象,并返回目標對象,
示例代碼如下:
const person = Object.assign({}, { name: '一碗周' }, { age: 18 }) console.log(person) // { name: '一碗周', age: 18 }
Object.getPrototypeOf()
:獲取原型對象;
Object.setPrototypeOf()
:設置原型對象。
在ES2015中提出了類的概念,在語法的層面上有了類,示例代碼如下:
class Person { constructor(age) { // 屬性 this.myName = '一碗周' this.age = age } // 靜態方法 static print() { console.log() } // 訪問器 get myName() { console.log('getter') return '一碗周' } set myName(v) { console.log('setter' + v) } setName(v) { this.myName = v } } const person = new Person(18) person.setName('ywanzhou') // 觸發 setter 訪問器 console.log(person.myName) // 觸發 getter 訪問器
在ES2015中提出ESModel模塊化規范,這是第一個官方層面的模塊化規范,在這個規范中允許我們使用export導出模塊,使用import引入模塊,
示例代碼如下:
import a from 'm' // 導入模塊 m 中的默認導出,將其命名為 a import a, { b } from 'm' // 導入模塊 m 中的默認導出以及單獨導入成員 b import * as A from 'm' // 導入模塊中的所有成員 import 'm' // 執行 m 模塊 export const b = 1 // 單獨導出 export default b // 默認導出 export { b } // 按需導出 export { b as bb } // 改名導出 export { b } from 'm' // 導入模塊 m 中的成員 b 并導出
ES2015新增了解構賦值的語法,允許我們使用按照一定的模式,在數組或者對象中提取指定的值,
示例代碼如下:
// 數組的解構賦值 let [name, age, hobby = 'coding' /* 結構賦值的默認值 */] = ['一碗周', 18] // 交換兩個變量的值 let a = 1 let b = 2 ;[a, b] = [b, a] console.log(a, b) // 2 1 // 對象的結構賦值 let { name: ObjName /* 解構賦值重命名 */, sex } = { name: '一碗周', sex: 1 } // 函數參數的解構賦值 function bar({ name, age }) { return name + age } bar({ name: '一碗周', age: 18 }) // 一碗周18
Symbol是ES2015中新增的一種數據類型,通過Symbol()
方法創建,可以傳遞一個字符串作為參數,用于描述該Symbol;
通過Symbol()方法創建的symbol值都是唯一的,示例代碼如下:
/** * 語法 * Symbol([description]) * * description -> 是一個可選的描述信息 */ // 創建一個 Symbol 類型的值 const mySymbol = Symbol() console.log(mySymbol) // Symbol() const myName = Symbol('一碗周') console.log(typeof myName) // symbol
Symbol還有一系列屬性和方法這里就不作介紹了。
Promise是ES2015中提供的一個異步解決方案,解決了回調地獄的問題。
通過Promise()
構造函數可以創建一個promise對象,每一個Promise對象都具有以下幾種狀態:
pending: 初始狀態,既不是成功,也不是失敗狀態。
resolved: 意味著操作成功完成。
rejected: 意味著操作失敗。
狀態的切換只有兩種,分別是:
pending→resolved
pending→resolved
一旦狀態發生改變,就不會再次改變
Promise
實例中存在要給then
方法,允許我們在Promise
實例中鏈式調用,每個then
方法還會返回一個Promise
實例,
如下圖所示:
示例代碼如下:
new Promise((resolve, reject) => { console.log('我是第一個Promise中的log') resolve() }) .then(() => { console.log('我是第一個then中的log') }) .then(() => { console.log('我是第二個then中的log,但是我出現了異常') throw new Error('Error') }) .then(() => { console.log('我是第三個then中的第一個回調的log,但是我不會執行,因為我上面出現了異常') }, () => { console.log('我是第三個then中的第二個回調的log,我執行了') }) .then(() => { console.log('我是第四個then中的log,我可以正常執行') }) /* 執行結果如下 我是第一個Promise中的log 我是第一個then中的log 我是第二個then中的log,但是我出現了異常 我是第三個then中的第二個回調的log,我執行了 我是第四個then中的log,我可以正常執行 */
有關Promise的一些方法如下:
Promise.prototype.then()
:它最多需要有兩個參數:Promise的成功和失敗情況的回調函數;
Promise.prototype.catch()
:等于then
方法的第二個參數;
Promise.all()
:將多個實例包裝成一個新實例,返回全部實例狀態變更后的結果數組(齊變更再返回)
Promise.race()
:將多個實例包裝成一個新實例,返回全部實例狀態優先變更后的結果(先變更先返回)
Promise.resolve()
:將對象轉為Promise對象(等價于new Promise(resolve => resolve())
)
Promise.reject()
:將對象轉為狀態為rejected
的Promise對象(等價于new Promise((resolve, reject) => reject())
)
Iterator即迭代器,它是一種接口,為各種不同的數據結構提供了統一的訪問機制,換句話說,只要有任何數據結構部署了迭代接口,就可以使用統一的方式的來遍歷它。
實現可迭代接口的數據結構,一般都自身實現或繼承了以Symbol.iterator
屬性的,就屬于可迭代對象。Symbol.iterator
屬性本身是一個函數,就是當前數據結構默認的遍歷器生成函數。
一個包含next()
方法的對象,才可以稱為一個迭代對象。next()
對象的會有返回一個對象,對象中包含兩個值,
如下所示:
value
:迭代器返回的任何JavaScript
值。done
為true
時可省略。
done
:一個布爾值,為false
時表示迭代未停止,為true
時立即停止迭代器,且可以省略value
的值。
JavaScript原生提供的迭代器接口如下圖所示:
現在我們為obj來實現一個迭代器,代碼如下:
const obj = { [Symbol.iterator] () { return { next () { console.log('迭代器執行了'); return { value: '', done: true // 標志是否結束,true表示已經結束 } } } } }
我們在next()
方法中添加了一個打印,為了驗證迭代器執行了,最終的運行結果為
迭代器執行了
Generator是ES2015中提供的一種異步編程解決方案,定義Generator函數在function
關鍵字和函數名中間使用*
星號,函數內部使用yield
關鍵字定義不同的狀態。
示例代碼如下:
function* testGenerator() { // yield定義一個狀態 yield '一碗周' yield 'es新特性' return 'generator' // 終結Generator,后面即使有yield關鍵字也無效 } const g = testGenerator() // 返回 Generator 對象,通過next()方法移動狀態 g.next() /* { value: '一碗周', done: false } */ g.next() /* { value: 'es新特性', done: false } */ g.next() /* { value: 'generator', done: true } */
Proxy對象用于創建一個代理對象,從而實現基本操作的攔截和自定義,基本操作包含13種,如下表所示:
攔截 ?法 | 觸發?式 |
---|---|
get(target, propKey, receiver) | 讀取某個屬性 |
set(target, propKey, value, receiver) | 寫?某個屬性 |
has(target, propKey) | in操作符 |
deleteProperty(target, propKey) | delete操作符 |
getPrototypeOf(target) | Object.getPropertypeOf() |
setPrototypeOf(target, proto) | Object.setPrototypeOf() |
isExtensible(target) | Object.isExtensible() |
preventExtensions(target) | Object.preventExtensions() |
getOwnPropertyDescriptor(target, propKey) | Object.getOwnPropertyDescriptor() |
defineProperty(target, propKey, propDesc) | Object.defineProperty() |
ownKeys(target) | Object.keys() 、Object.getOwnPropertyNames()、Object.getOwnPropertySymbols() |
apply(target, thisArg, args) | 調??個函數 |
construct(target, args) | ? new 調??個函數 |
Vue3就是基于Proxy
進行編寫的,下面這段代碼展示了Proxy
對象的使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet" /> <title>通過set自動更新dom</title> </head> <body> <p class="card" style="width: 300px; margin: 100px auto"> <p class="card-body"> <h2 id="name"></h2> <button id="btn" class="btn btn-primary">修改</button> </p> </p> <script> // 獲取DOM節點 const name = document.getElementById('name') const btn = document.getElementById('btn') // 定義一個修改值的函數 const updateDOM = (el, value) => { el.innerHTML = value } const person = new Proxy({ name: '一碗粥', }, { set(target, propKey, value) { // 如果里面的值改變就去調用我們的updateDOM updateDOM(name, value) target[propKey] = value return true }, }) name.innerHTML = person.name // 點擊按鈕觸發修改操作 btn.addEventListener('click', () => { person.name === '一碗周' ? (person.name = '一碗粥') : (person.name = '一碗周') }) </script> </body> </html>
上面的代碼就利用set方法進行數據綁定,如果對象發生改變,就自動更新我們的DOM。
Reflect是ECMAScript2015提供的一個對象,它提供了一些攔截JavaScript操作的靜態方法,這些方法與Proxy中的handlers
中的方法一致。
Reflect并不是一個構造函數,也就是說它不能夠被實例化。
Proxy
對象中的每一個攔截操作(例如:get
、delete
等),內部都對應的調用了Reflect
的方法。它提供的靜態方法與Proxy中的handlers
中的方法名稱都一致,
具體如下:
默認調? | 功能 |
---|---|
Reflect.get() | 獲取對象身上某個屬性的值 |
Reflect.set() | 在對象上設置屬性 |
Reflect.has() | 判斷一個對象是否存在某個屬性 |
Reflect.deleteProperty() | 刪除對象上的屬性 |
Reflect.getPrototypeOf() | 獲取指定對象原型的函數 |
Reflect.setPrototypeOf() | 設置或改變對象原型的函數 |
Reflect.isExtensible() | 判斷一個對象是否可擴展 (即是否能夠添加新的屬性) |
Reflect.preventExtensions() | 阻止新屬性添加到對象 |
Reflect.getOwnPropertyDescriptor() | 獲取給定屬性的屬性描述符 |
Reflect.defineProperty() | 定義或修改一個對象的屬性 |
Reflect.ownKeys() | 返回由目標對象自身的屬性鍵組成的數組 |
Reflect.apply() | 對一個函數進行調用操作,同時可以傳入一個數組作為調用參數 |
Reflect.construct() | 對構造函數進行 new操作,實現創建類的實例 |
Set
、Map
、WeakSet
、WeakMap
是ES2015中新增的幾個對象:
Set
和WeakSet
與數組類似,準確的它他們是集合,這兩者的區別就是Set
可以存儲任何數據類型,而WeakSet
只能存儲對象的引用,而且是弱引用;
Set對象在實際開發中最常見的就是實現數據去重,示例代碼如下:
const arr = [1, 2, 2, 3, 4, 3, 5] const set = new Set(arr) // set對象可以使用 ... 展開 所有項 console.log([...set]) // [ 1, 2, 3, 4, 5 ]
Map
和WeakMap
與對象類似,存儲方式是鍵值對形式的,這兩者的區別Map
的鍵值對都是可以是任意的而WeakMap
鍵必須是對象的引用而值可以是任意類型的。
ES2016發布的新特性比較少,主要就兩個新特性,如下圖所示:
ES2016中新增指數**
,也叫冪運算符,與Math.pow()有著一樣的功能,
示例代碼如下:
console.log(2 ** 10 === Math.pow(2, 10)) // true
在ES2016中在數組原型上增加了includes()
方法,該方法用于判斷一個數組中是否包含指定的值,返回一個布爾值,
示例代碼如下:
const arr = [1, 2, 3, 4, 5, NaN] console.log(arr.indexOf(NaN)) // -1 console.log(arr.includes(NaN)) // true
值得注意的是使用includes()
時NaN
與NaN
、+0
與-0
是相等的。
Promise的出現雖然解決了回調地獄的問題,但是如果鏈式調用特別多的話可讀性還是會變差,在ES2017中新增了 async/await語法糖解決了這個問題。
Promise的寫法如下:
;(function () { function promise(v) { return new Promise((resolve, reject) => { resolve(v) }) } const p = promise(1) p.then(res => { return promise(res) }).then(res => { console.log(res) }) })()
如果下一個Promise依賴于上一個,這種鏈式調用就會非常的長,現在我們用 async/await語法糖改寫一下:
;(async function () { function promise(v) { return new Promise((resolve, reject) => { resolve(v) }) } const r1 = await promise(1) const r2 = await promise(r1) const res = await promise(r2) console.log(res) })()
可以看到,我們可以利用 async/await語法糖將Promise改寫為平級的寫法。
ES2017中新增了Atomics對象,該對象提供了一系列靜態方法用于操作SharedArrayBuffer和ArrayBuffer對象,該對象并不能使用new
關鍵字進行實例化,僅僅提供了一些靜態的屬性和方法
在ES2017中為Object擴展了三個靜態方法,如下所示:
Object.values()
:返回一個給定對象自身的所有可枚舉屬性值的數組;
Object.entries()
:返回一個給定對象自身可枚舉屬性的鍵值對數組;
Object.getOwnPropertyDescriptors()
:返回給定對象所有自有屬性的屬性描述符。
在ES2017中允許我們在函數參數列表的最后面添加逗號,這個小特性非常的有用,因為為尾逗號的更新的時候僅僅需要改動一行代碼,如果不適用尾逗號則是改動兩行代碼。
實例代碼如下:
function fun( aaaaa, bbbbb, ccccc, ) {}
如果存在尾逗號,只需要在最后面添加一行就好;如果不存在則需要在后面添加要給逗號,然后在添加一行。這在版本管理中就改動了兩行,而不是一行。
在ES2017中為字符串新增了兩個實例方法,分別是:
padStart()
:在字符串開頭填充空格;
padEnd()
:在字符串結尾填充空格;
示例代碼如下:
const str = '一碗周' console.log(str.padStart(10)) /* 一碗周 */ console.log(str.padEnd(10)) /* 一碗周 */
在ES2018中新增了for await...of
語句,該用于可以遍歷異步可迭代對象,
示例代碼如下:
var asyncIterable = { [Symbol.asyncIterator]() { return { i: 0, next() { if (this.i < 3) { return Promise.resolve({ value: this.i++, done: false }) } return Promise.resolve({ done: true }) }, } }, } ;(async function () { for await (num of asyncIterable) { console.log(num) } })() // 0 // 1 // 2
在ES2018中,對正則表達式進行了如下擴展:
正則表達式分組命名:
在ES2018之前,我們無法對正則表達式中的分組命名,在ES2018中引入了該特性,該特性既方便了正則的閱讀又方便了引用,
示例代碼如下:
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ const matchObj = RE_DATE.exec('2022-02-22') const year = matchObj.groups.year // 2022 const month = matchObj.groups.month // 02 const day = matchObj.groups.day // 22
s修飾符/dotALl模式:新增的s修飾符允許使用.
匹配任意單個字符,****屬性表明是否在正則表達式中一起使用"s
"修飾符。
反向斷言:ES2018之前僅存在正向斷言,而ES2018中新增了反向斷言和反向否定斷言。
ES2015中新增數組的展開運算符,在ES2018中將這一特性加入到了對象中,示例代碼如下:
const n = { name: '一碗周' } const a = { age: 18 } const person = { ...n, ...a } // 合并對象 console.log(person) // { name: '一碗周', age: 18 }
finally()
方法會返回一個Promise
對象,當promise的狀態變更,不管是變成rejected
或者fulfilled
,最終都會執行finally()
的回調。
示例代碼如下:
fetch(url) .then(res => { console.log(res) }) .catch(error => { console.log(error) }) .finally(() => { console.log('結束') })
在ES2019中優化了以下兩個內容:
Function.prototype.toString()
:返回的函數體包含注釋與空格;
try...catch
:語句中的catch
允許不使用參數,示例代碼如下:
try { console.log('一碗周') } catch { console.error('一碗周') }
String.prototype.trimStart
:用于去除字符串左邊的空格;
String.prototype.trimLeft
:它是trimStart
的別名
String.prototype.trimEnd
:用于去除字符串右邊的空格;
String.prototype.trimRight
:它是trimEnd
的別名
在ES2019中擴展了兩個數組方法,分別是:
Array.prototype.flat()
:該方法會按照一個可指定的深度遞歸遍歷數組,并將所有元素與遍歷到的子數組中的元素合并為一個新數組返回;簡單的說就是實現數組的扁平化。
const arr = [0, 1, 2, [3, 4]] console.log(arr.flat()) // [ 0, 1, 2, 3, 4 ]
Array.prototype.flatMap()
:該方法映射且扁平化數組,返回新數組(只能展開一層數組)。
ES2019中新增的Object.fromEntries()
方法把鍵值對列表轉換為一個對象,是Object.entries()
方法的反操作,
示例代碼如下:
const person = { name: '一碗周', age: '18', } const e = Object.entries(person) const p = Object.fromEntries(e) console.log(p) // { name: '一碗周', age: '18' }
description
是一個只讀屬性,它會返回創建Symbol對象時的那個可選的描述字符串。
模塊化
在ES2020中加入了動態導入,也就是我們需要該模塊的時候才會進行加載,這可以減少開銷和頁面加載時間,示例代碼如下:
import('/modules/my-module.js').then(module => { // Do something with the module. })
動態導入使用import()
方法,它返回一個Promise。
在ES2020中,還為import
增加一個meta
對象,該對象給JavaScript模塊暴露了特定上下文的元數據屬性的對象。
BigInt的出現時解決JavaScript中允許的最大數字是2**53-1
的問題,BigInt
可以表示任意大的整數。
const theBiggestInt = 9007199254740991n; const alsoHuge = BigInt(9007199254740991); // ? 9007199254740991n const hugeString = BigInt("9007199254740991"); // ? 9007199254740991n const hugeHex = BigInt("0x1fffffffffffff"); // ? 9007199254740991n const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111"); // ? 9007199254740991n
ES2020中引入globalThis
,它是對全局對象的引入,在Node是的全局對象是Global
,而瀏覽器環境是Window
;如下代碼展示的在有沒有GlobalThis
的區別:
// 之前 var getGlobal = function () { 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 (typeof globals.setTimeout !== 'function') { // no setTimeout in this environment! }
// 之后 if (typeof globalThis.setTimeout !== 'function') { // no setTimeout in this environment! }
空值合并運算符是由兩個問號來表示,該運算符也是一個邏輯運算符,該運算符與邏輯或運算符類似。其計算規則為,只要左運算元為null
或者undefined
,則返回右運算元,否則返回左運算元。而邏輯或運算符只有左運算元轉換為boolean
類型后為false
,就返回右運算元。
示例代碼如下:
console.log(null ?? 10) // 10 console.log(undefined ?? 10) // 10 console.log(false ?? 10) // false
該運算符用于為沒有值的變量賦值很有用,例如:如果這個數沒有值,就為其賦值,否則不賦值,
示例代碼如下:
var value // 如果value的值不為 null 或者 undefined 為其賦值10 value = value ?? 10 console.log(value) // 10
值得注意的是空值合并運算符與邏輯與和邏輯或不能同時使用,否則會拋出異常,解決方案是通過使用
()
來表明優先級
可選鏈操作符用于讀取某對象鏈下深處屬性的值,使用這個操作符不必驗證對象下的每個屬性必須存在,例如我們想要訪問A.a.b
這個屬性時,我們首先需要確保A
存在,然后需要確保A.a
存在,才可以訪問A.a.b
這個屬性,不然就會報錯。
使用可選鏈操作符就不會出現這樣的問題,當我們訪問某個屬性時,只要有一處不存在,就會返回undefind
,不會報錯。
var A = {} // console.log(A.a.b) // 報錯 console.log(A.a?.b) // undefined
可選鏈操作符也可用于對象下方法的調用,示例代碼如下:
var obj = {} // 如果存在 obj.fun() 這個方法,下面則會直接調用,如果不存在則會返回undefined obj.fun?.A()
Promise.allSettled()
方法返回一個在所有給定的 promise 都已經resolved或rejected后的 promise,并帶有一個對象數組,每個對象表示對應的 promise 結果。
replaceAll()
方法返回一個新字符串,新字符串的內容是經過替換的,實例代碼如下:
const str = '一碗粥' const newStr = str.replaceAll('粥', '周') console.log(newStr) // 一碗周
嚴格意義上講數值分隔符(_
)并不屬于一個運算符,其作用就是使數字更加利于閱讀,例如下面的代碼
console.log(1_0000_0000) // 100000000
這個符號僅僅起到了便于閱讀的目的,有與沒有的結果并不影響,看下面的代碼
1_1 === 11 // true
ES2021中新增的WeakRef
對象允許您保留對另一個對象的弱引用,而不會阻止被弱引用對象被GC回收。
ES2021中新增的Promise.any()
方法,它接受的參數和與promise.all()
是一致的,唯一不同的是,Promise.any()
方法接受的可迭代對象中沒有一個promise成功(即所有的promises都失敗/拒絕),就返回一個失敗的promise和AggregateError類型的實例。
ES2021中新增了一些賦值運算符,具體如下:
&&=
||=
??=
實際上它與普通的賦值運算符一致,示例代碼如下:
const [f1, f2, f3] = [true, false] f1 &&= '一碗周' // 等同于 str = str && '一碗周' f2 ||= '一碗周' // 等同于 str = str || '一碗周' f3 ??= '一碗周' // 等同于 str = str ?? '一碗周'
在ES2022中允許我們并不在constructor
中定義類的成員,示例代碼如下:
class C { myName = '一碗周' } /* 兩者是一致的 */ class C { constructor() { myName = '一碗周' } }
如果成員只聲明不初始化它的默認值是undefined。
在ES2022中允許我們使用#
開頭命名的變量作為類的私有成員,
示例代碼如下:
class C { #myName = '一碗周' } const c = new C() console.log(#myName) // Private field '#myName' must be declared in an enclosing class
在ES2022中新增了允許在頂層使用await
,在頂層可以不適用async
函數進行包裹,示例代碼如下:
import { AsyncFun } from 'module' await AsyncFun() console.log(123)
Object.hasOwn()
方法用于判斷某個對象上是否具有某個屬性,示例代碼如下:
const person = { name: '一碗周', age: 18, } console.log(Object.hasOwn(person, 'name')) // true console.log(Object.hasOwn(person, 'sex')) // false
ES2022中新增的at()
方法,它的作用是獲取數組中的某個成員,它的參數是數組的索引,與直接使用索引的方式不同,它允許我們傳遞負值,等同于從后面倒數,示例代碼如下:
const arr = [1, 2, 3, 4, 5, 6] console.log(arr.at(-1)) // 6 // 等同于 arr[arr.length - 1]
正則表達式增加了一個/d
修飾符,當使用正則表達式的exec()
方法時,如果有/d
修飾符,那么結果會多返回一個indices屬性,用來表示匹配的結果的在原字符串中的起始index值。
示例代碼如下:
const str = 'JavaScript' const r = /a/d const m = r.exec(str) console.log(m.indices[0]) //[ 1, 2 ]
到此,關于“JavaScript ECMAScript6所有新特性怎么用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。