溫馨提示×

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

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

JavaScript?ECMAScript6所有新特性怎么用

發(fā)布時(shí)間:2022-08-16 09:47:53 來源:億速云 閱讀:142 作者:iii 欄目:web開發(fā)

這篇文章主要介紹“JavaScript ECMAScript6所有新特性怎么用”,在日常操作中,相信很多人在JavaScript ECMAScript6所有新特性怎么用問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”JavaScript ECMAScript6所有新特性怎么用”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

JavaScript?ECMAScript6所有新特性怎么用

ES2015(ES6)

ES2015是改動(dòng)最大的一個(gè)版本,基本上對(duì)ES2015之前的所有的內(nèi)容都做了擴(kuò)展,大體如下所示:

let、const關(guān)鍵字和塊級(jí)作用域

在ES6之前只有一種聲明變量的方式,就是使用var關(guān)鍵字,在ES2015中新增了letconst關(guān)鍵字來聲明變量與常量,

代碼如下:

// 聲明變量
let v = 100
v = 200
// 聲明常量
const V = 200
// 修改常量
// V = 300 // 報(bào)錯(cuò)

同時(shí)使用letconst關(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ū)的特性。

函數(shù)的擴(kuò)展

在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

數(shù)值的擴(kuò)展

在ES2015中對(duì)數(shù)值的擴(kuò)展主要時(shí)為MathNumber兩個(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)

字符串的擴(kuò)展

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()判斷字符串是否存在原始字符串的尾部

數(shù)組的擴(kuò)展

在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, '一碗周' ] ]

對(duì)象的擴(kuò)展

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)出

解構(gòu)賦值

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

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

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í)例,

如下圖所示:

JavaScript?ECMAScript6所有新特性怎么用

示例代碼如下:

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

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值。donetrue時(shí)可省略。

  • done:一個(gè)布爾值,為false時(shí)表示迭代未停止,為true時(shí)立即停止迭代器,且可以省略value的值。

JavaScript原生提供的迭代器接口如下圖所示:

JavaScript?ECMAScript6所有新特性怎么用

現(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

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和Reffect

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

SetMap、WeakSet、WeakMap是ES2015中新增的幾個(gè)對(duì)象:

  • SetWeakSet與數(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 ]
  • MapWeakMap與對(duì)象類似,存儲(chǔ)方式是鍵值對(duì)形式的,這兩者的區(qū)別Map的鍵值對(duì)都是可以是任意的而WeakMap鍵必須是對(duì)象的引用而值可以是任意類型的。

ES2016(ES7)

ES2016發(fā)布的新特性比較少,主要就兩個(gè)新特性,如下圖所示:

JavaScript?ECMAScript6所有新特性怎么用

指數(shù)運(yùn)算符

ES2016中新增指數(shù)**,也叫冪運(yùn)算符,與Math.pow()有著一樣的功能,

示例代碼如下:

console.log(2 ** 10 === Math.pow(2, 10)) // true

Array.prototype.includes()方法

在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í)NaNNaN、+0-0是相等的。

ES2017(ES8)

JavaScript?ECMAScript6所有新特性怎么用

async/await語(yǔ)法糖

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í)的寫法。

Atomics對(duì)象

ES2017中新增了Atomics對(duì)象,該對(duì)象提供了一系列靜態(tài)方法用于操作SharedArrayBuffer和ArrayBuffer對(duì)象,該對(duì)象并不能使用new關(guān)鍵字進(jìn)行實(shí)例化,僅僅提供了一些靜態(tài)的屬性和方法

對(duì)象擴(kuò)展

在ES2017中為Object擴(kuò)展了三個(gè)靜態(tài)方法,如下所示:

  • Object.values():返回一個(gè)給定對(duì)象自身的所有可枚舉屬性值的數(shù)組;

  • Object.entries():返回一個(gè)給定對(duì)象自身可枚舉屬性的鍵值對(duì)數(shù)組;

  • Object.getOwnPropertyDescriptors():返回給定對(duì)象所有自有屬性的屬性描述符。

函數(shù)擴(kuò)展

在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)了兩行,而不是一行。

字符串?dāng)U展

在ES2017中為字符串新增了兩個(gè)實(shí)例方法,分別是:

  • padStart():在字符串開頭填充空格;

  • padEnd():在字符串結(jié)尾填充空格;

示例代碼如下:

const str = '一碗周'
console.log(str.padStart(10)) /*        一碗周 */
console.log(str.padEnd(10))   /* 一碗周        */

ES2018(ES9)

JavaScript?ECMAScript6所有新特性怎么用

異步迭代

在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

正則的擴(kuò)展

在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中新增了反向斷言反向否定斷言

對(duì)象展開運(yùn)算符

ES2015中新增數(shù)組的展開運(yùn)算符,在ES2018中將這一特性加入到了對(duì)象中,示例代碼如下:

const n = { name: '一碗周' }
const a = { age: 18 }
const person = { ...n, ...a }
// 合并對(duì)象
console.log(person) // { name: '一碗周', age: 18 }

Promise.prototype.finally()

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(ES10)

JavaScript?ECMAScript6所有新特性怎么用

優(yōu)化

在ES2019中優(yōu)化了以下兩個(gè)內(nèi)容:

  • Function.prototype.toString():返回的函數(shù)體包含注釋與空格;

  • try...catch:語(yǔ)句中的catch允許不使用參數(shù),示例代碼如下:

try {
  console.log('一碗周')
} catch {
  console.error('一碗周')
}

trimStart()/trimLeft()和trimEnd()/trimRight()

  • String.prototype.trimStart:用于去除字符串左邊的空格;

  • String.prototype.trimLeft:它是trimStart的別名

  • String.prototype.trimEnd:用于去除字符串右邊的空格;

  • String.prototype.trimRight:它是trimEnd的別名

數(shù)組的擴(kuò)展

在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ù)組)。

Object.fromEntries()

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' }

Symbol.prototype.descrption

description是一個(gè)只讀屬性,它會(huì)返回創(chuàng)建Symbol對(duì)象時(shí)的那個(gè)可選的描述字符串。

ES2020(ES11)

JavaScript?ECMAScript6所有新特性怎么用

模塊化

在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數(shù)據(jù)類型

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

globalThis對(duì)象

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)算符

空值合并運(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()

Promise.allSettled()方法返回一個(gè)在所有給定的 promise 都已經(jīng)resolved或rejected后的 promise,并帶有一個(gè)對(duì)象數(shù)組,每個(gè)對(duì)象表示對(duì)應(yīng)的 promise 結(jié)果。

ES2021(ES12)

JavaScript?ECMAScript6所有新特性怎么用

String.prototype.replaceAll()

replaceAll()方法返回一個(gè)新字符串,新字符串的內(nèi)容是經(jīng)過替換的,實(shí)例代碼如下:

const str = '一碗粥'
const newStr = str.replaceAll('粥', '周')
console.log(newStr) // 一碗周

數(shù)值分隔符

嚴(yán)格意義上講數(shù)值分隔符(_)并不屬于一個(gè)運(yùn)算符,其作用就是使數(shù)字更加利于閱讀,例如下面的代碼

console.log(1_0000_0000) // 100000000

這個(gè)符號(hào)僅僅起到了便于閱讀的目的,有與沒有的結(jié)果并不影響,看下面的代碼

1_1 === 11 // true

WeakRef

ES2021中新增的WeakRef對(duì)象允許您保留對(duì)另一個(gè)對(duì)象的弱引用,而不會(huì)阻止被弱引用對(duì)象被GC回收。

Promise.any()

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

JavaScript?ECMAScript6所有新特性怎么用

class的擴(kuò)展

在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

await在頂層使用

在ES2022中新增了允許在頂層使用await,在頂層可以不適用async函數(shù)進(jìn)行包裹,示例代碼如下:

import { AsyncFun } from 'module'
await AsyncFun()
console.log(123)

Object.hasOwn()

Object.hasOwn()方法用于判斷某個(gè)對(duì)象上是否具有某個(gè)屬性,示例代碼如下:

const person = {
  name: '一碗周',
  age: 18,
}
console.log(Object.hasOwn(person, 'name')) // true
console.log(Object.hasOwn(person, 'sex')) // false

Array.prototype.at()

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修飾符

正則表達(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í)用的文章!

向AI問一下細(xì)節(jié)

免責(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)容。

AI