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