ECMAScript 是一種由 Ecma
國際(前身為歐洲計算機制造商協(xié)會)通過 ECMA-262
標準化的腳本程序設計語言薯演。這種語言在萬維網(wǎng)上應用廣泛,它往往被稱為 JavaScript
或 JScript
允瞧,所以它可以理解為是 JavaScript
的一個標準翰守,但實際上后兩者是 ECMA-262
標準的實現(xiàn)和擴展库糠。
ES6(ES2015)
-
let
和const
var let const 變量提升 √ × × 全局變量 √ × × 重復聲明 √ × × 重新賦值 √ √ × 暫時性死區(qū) × √ √ 塊作用域 × √ √ 只聲明不初始化 √ √ × 暫時性死區(qū)(
TDZ
):ES6
明確規(guī)定沙兰,如果區(qū)塊中存在let
命令,這個區(qū)塊對這些命令聲明的變量二打,從一開始就形成了封閉作用域县忌。只要一進入當前作用域,所要使用的變量就已經(jīng)存在了继效,但是不可獲取症杏,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量瑞信。let厉颤、const 聲明的變量 ,不會綁定在 window 上。
-
類(
Class
)
在ES6
之前,如果我們要生成一個實例對象拇惋,傳統(tǒng)的方法就是寫一個構造函數(shù),例子如下:function Person(name, age) { this.name = name this.age = age } Person.prototype.information = function () { return 'My name is ' + this.name + ', I am ' + this.age }
但是在
ES6
之后帜乞,我們只需要寫成以下形式:class Person { constructor(name, age) { this.name = name this.age = age } information() { return 'My name is ' + this.name + ', I am ' + this.age } }
函數(shù)參數(shù)默認值(Function parameter defaults)
模板字符串(Template string)
解構賦值(Destructuring assignment)
模塊化(Module)
擴展操作符(Spread operator)
-
Promise
Promise
是ES6
提供的一種異步解決方案,比回調函數(shù)更加清晰明了筐眷。
所謂Promise
黎烈,簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說照棋,Promise 是一個對象资溃,從它可以獲取異步操作的消息。
Promise
提供統(tǒng)一的API
烈炭,各種異步操作都可以用同樣的方法進行處理溶锭。Promise
對象有以下兩個特點:- 對象的狀態(tài)不受外界影響。
Promise
對象代表一個異步操作符隙,有三種狀態(tài):Pending
(進行中)趴捅、Resolved
(已完成,又稱 Fulfilled)和Rejected
(已失斉摺)驻售。只有異步操作的結果,可以決定當前是哪一種狀態(tài)更米,任何其他操作都無法改變這個狀態(tài)。 - 一旦狀態(tài)改變毫痕,就不會再變征峦,任何時候都可以得到這個結果。
Promise
對象的狀態(tài)改變消请,只有兩種可能:從Pending
變?yōu)?Resolved
和從Pending
變?yōu)?Rejected
栏笆。
缺點:首先,無法取消
Promise
臊泰,一旦新建它就會立即執(zhí)行蛉加,無法中途取消。其次缸逃,如果不設置回調函數(shù)针饥,Promise
內部拋出的錯誤,不會反應到外部需频。第三丁眼,當處于Pending
狀態(tài)時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)昭殉。var promise = new Promise(function(resolve, reject) { // ... some code if (/* 異步操作成功 */){ // 若 resolve(value); 后面還有語句苞七,也會同步執(zhí)行。若為 return resolve(value); 則后面的語句不會執(zhí)行 resolve(value); } else { reject(error); } }) promise.then(function(value) { // success }, function(error) { // failure })
Promise.all()
:用于將多個Promise
實例(如果不是挪丢,就會先調用Promise.resolve
方法蹂风,將參數(shù)轉為Promise
實例),包裝成一個新的Promise
實例乾蓬。
(1)只有這幾個實例的狀態(tài)都變成resolved
惠啄,p
的狀態(tài)才會變成resolved
,此時傳遞給p
的回調函數(shù)的參數(shù)為返回值組成的數(shù)組。
(2)只要實例中有一個被rejected
礁阁,p
的狀態(tài)就變成rejected
巧号,此時第一個被reject
的實例的返回值,會傳遞給p
的回調函數(shù)姥闭。如果p2
沒有自己的catch
方法丹鸿,就會調用Promise.all()
的catch
方法。Promise.allSettled()
:接受一組Promise
實例作為參數(shù)棚品,包裝成一個新的Promise
實例靠欢。只有等到所有這些參數(shù)實例都返回結果,不管是fulfilled
還是rejected
铜跑,包裝實例才會結束门怪。返回值allSettledPromise
,狀態(tài)只可能變成fulfilled
锅纺。它的監(jiān)聽函數(shù)接收到的參數(shù)是數(shù)組results
(含fulfilled
的結果 orrejected
的結果)掷空。Promise.race()
:接受一組Promise
實例作為參數(shù),包裝成一個新的Promise
實例囤锉。var p = Promise.race([p1, p2, p3])
只要p1坦弟、p2、p3
之中有一個實例率先改變狀態(tài)官地,p
的狀態(tài)就跟著改變酿傍。那個率先改變的Promise
實例的返回值,就傳遞給p
的回調函數(shù)驱入。Promise.any()
:接受一組Promise
實例作為參數(shù)赤炒,包裝成一個新的Promise
實例。只要參數(shù)實例有一個變成fulfilled
狀態(tài)亏较,包裝實例就會變成fulfilled
狀態(tài)莺褒;如果所有參數(shù)實例都變成rejected
狀態(tài),包裝實例就會變成rejected
狀態(tài)宴杀,參數(shù)為成員錯誤結果數(shù)組癣朗。-
Promise.resolve()
:將現(xiàn)有對象轉為Promise
對象。Promise.resolve('foo') // 等價于 new Promise(resolve => resolve('foo'))
-
Promise.reject()
:將現(xiàn)有對象轉為Promise
對象旺罢,該實例的狀態(tài)為rejected
旷余。var p = Promise.reject('出錯了'); // 等價于 var p = new Promise((resolve, reject) => reject('出錯了'))
done()
:總是處于回調鏈的尾端,保證拋出任何可能出現(xiàn)的錯誤finally()
:用于指定不管Promise
對象最后狀態(tài)如何扁达,都會執(zhí)行的操作正卧。它與done
方法的最大區(qū)別,它接受一個普通的無參數(shù)的回調函數(shù)作為參數(shù)跪解,該函數(shù)不管怎樣都必須執(zhí)行炉旷,與狀態(tài)無關,不依賴于Promise
的執(zhí)行結果。-
Promise.try()
:讓同步函數(shù)同步執(zhí)行窘行,異步函數(shù)異步執(zhí)行饥追,并且讓它們具有統(tǒng)一的API
const f = () => console.log('now'); Promise.try(f); console.log('next'); // now // next
- 對象的狀態(tài)不受外界影響。
-
for…of
const array1 = ['a', 'b', 'c'] for (const element of array1) { console.log(element) }
for ... in ; for ... of 區(qū)別
- for ... in 獲取的是對象的鍵名;for ... of 遍歷獲取的是對象的鍵值
- for ... in 會遍歷對象的整個原型鏈罐盔,性能非常差但绕,不推薦使用;而 for ... of 只遍歷當前對象惶看,不會遍歷原型鏈
- 對于數(shù)組的遍歷捏顺,for ... in 會返回數(shù)組中所有可枚舉的屬性(包括原型鏈上可枚舉的屬性);for ... of 只返回數(shù)組的下標對應的屬性值
- 對于普通對象纬黎,沒有部署原生的 iterator 接口幅骄,直接使用 for...of 會報錯,也可以使用 Object.keys(obj) 方法將對象的鍵名生成一個數(shù)組本今,然后遍歷這個數(shù)組
- forEach 循環(huán)無法中途跳出拆座,break 命令或 return 命令都不能奏效;for...of 循環(huán)可以與 break冠息、continue 和 return 配合使用懂拾,跳出循環(huán)
- for...in 循環(huán)主要是為了遍歷對象而生,不適用于遍歷數(shù)組铐达;for...of 循環(huán)可以用來遍歷數(shù)組、類數(shù)組對象檬果,字符串瓮孙、Set、Map 以及 Generator 對象
-
Symbol
symbol
是一種基本數(shù)據(jù)類型选脊,表示獨一無二的值杭抠。Symbol()
函數(shù)會返回symbol
類型的值,該類型具有靜態(tài)屬性和靜態(tài)方法恳啥。
每個從Symbol()
返回的symbol
值都是唯一的偏灿。一個symbol
值能作為對象屬性的標識符;這是該數(shù)據(jù)類型僅有的目的钝的。const symbol1 = Symbol(); const symbol2 = Symbol(42); const symbol3 = Symbol('foo'); console.log(typeof symbol1); // "symbol" console.log(symbol3.toString()); // "Symbol(foo)" console.log(Symbol('foo') === Symbol('foo')); // false
-
迭代器(Iterator)/ 生成器(Generator)
迭代器(Iterator
)是一種迭代的機制翁垂,為各種不同的數(shù)據(jù)結構提供統(tǒng)一的訪問機制。任何數(shù)據(jù)結構只要內部有Iterator
接口硝桩,就可以完成依次迭代操作沿猜。
一旦創(chuàng)建,迭代器對象可以通過重復調用next()
顯式地迭代碗脊,從而獲取該對象每一級的值啼肩,直到迭代完,返回{ value: undefined, done: true }
祈坠。function* makeRangeIterator(start = 0, end = Infinity, step = 1) { for (let i = start; i < end; i += step) { yield i; } } var a = makeRangeIterator(1,10,2) a.next() // {value: 1, done: false} a.next() // {value: 3, done: false} a.next() // {value: 5, done: false} a.next() // {value: 7, done: false} a.next() // {value: 9, done: false} a.next() // {value: undefined, done: true}
-
Set / WeakSet
Set
對象允許你存儲任何類型的唯一值儒陨,無論是原始值或者是對象引用。const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5] console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]
WeakSet
結構與Set
類似州叠,但區(qū)別有以下兩點:-
WeakSet
對象中只能存放對象引用逆甜,不能存放值斟或,而Set
對象都可以亚享。 -
WeakSet
對象中存儲的對象值都是被弱引用的亭罪,如果沒有其他的變量或屬性引用這個對象值,則這個對象值會被當成垃圾回收掉箩祥。正因為這樣肆氓,WeakSet
對象是無法被枚舉的,沒有辦法拿到它包含的所有元素蕉陋。
const ws = new WeakSet() const obj = {} const foo = {} ws.add(window) ws.add(obj) ws.has(window) // true ws.has(foo) // false, 對象 foo 并沒有被添加進 ws 中 ws.delete(window) // 從集合中刪除 window 對象 ws.has(window) // false, window 對象已經(jīng)被刪除了 ws.clear() // 清空整個 WeakSet 對象
-
-
Map / WeakMap
Map
對象保存鍵值對。任何值(對象或者原始值) 都可以作為一個鍵或一個值惋嚎。甚至可以使用NaN
來作為鍵值。const myMap = new Map(); myMap.set(NaN, "not a number"); myMap.get(NaN); // "not a number" const otherNaN = Number("foo"); myMap.get(otherNaN); // "not a number"
WeakMap
對象是一組鍵 / 值對的集合站刑,其中的鍵是弱引用的另伍。其鍵必須是對象,而值可以是任意的绞旅。跟Map
的區(qū)別與Set
跟WeakSet
的區(qū)別相似摆尝。const o1 = {}; const o2 = function(){}; const o3 = window; const wm1 = new WeakMap(); wm1.set(o1, 37); wm1.has(o1); // true wm1.delete(o1); wm1.has(o1); // false wm1.set(o2, "azerty"); wm1.get(o2); // "azerty" wm1.has(o2); // true const wm2 = new WeakMap(); wm2.set(o1, o2); // value可以是任意值,包括一個對象 wm2.get(o2); // undefined,wm2中沒有o2這個鍵 wm2.has(o2); // false wm2.set(o3, undefined); wm2.get(o3); // undefined,值就是undefined wm2.has(o3); // true (即使值是undefined) wm2.set(wm1, wm2); // 鍵和值可以是任意對象,甚至另外一個WeakMap對象 const wm3 = new WeakMap(); wm3.set(o1, 37); wm3.get(o1); // 37 wm3.clear(); wm3.get(o1); // undefined,wm3已被清空
-
Proxy / Reflect
Proxy
對象用于定義基本操作的自定義行為(如屬性查找,賦值因悲,枚舉堕汞,函數(shù)調用等)。
Reflect
是一個內置的對象晃琳,它提供攔截JavaScript
操作的方法讯检。這些方法與Proxy
的方法相同琐鲁。Reflect
不是一個函數(shù)對象,因此它是不可構造的人灼。const observe = (data, callback) => { return new Proxy(data, { get(target, key) { return Reflect.get(target, key) }, set(target, key, value, proxy) { callback(key, value); target[key] = value; return Reflect.set(target, key, value, proxy) } }) } const FooBar = { open: false }; const FooBarObserver = observe(FooBar, (property, value) => { property === 'open' && value ? console.log('FooBar is open!!!') : console.log('keep waiting'); }); console.log(FooBarObserver.open) // false FooBarObserver.open = true // FooBar is open!!! FooBarObserver.open = false // keep waiting
-
Regex對象的擴展
-
u 修飾符:
為了處理碼點大于\uFFFF
的Unicode
字符(也就是說围段,會正確處理四個字節(jié)的UTF-16
編碼);\uD83D\uDC2A
是一個字符投放,但是es5
不支持四個字節(jié)的UTF-16
奈泪,會將其識別成兩個字符;加了u
修飾符之后灸芳,es6
會將其識別成一個字符涝桅。// i 修飾符:不區(qū)分大小寫 /[a-z]/i.test('\u212A') // false /[a-z]/iu.test('\u212A') // true
-
y 修飾符:“粘連”(sticky)修飾符
y
修飾符的作用與g
修飾符類似,也是全局匹配烙样,后一次匹配都從上一次匹配成功的下一個位置開始冯遂。不同之處在于,g
修飾符只要剩余位置中存在匹配就可误阻,而y
修飾符確保匹配必須從剩余的第一個位置開始债蜜,這也就是“粘連”的涵義。var s = 'aaa_aa_a'; var r1 = /a+/g; var r2 = /a+/y; r1.exec(s) // ["aaa"] r2.exec(s) // ["aaa"] r1.exec(s) // ["aa"] r2.exec(s) // null
-
查看RegExp構造函數(shù)的修飾符
new RegExp(/abc/ig, 'i').flags // "i"
-
-
Array 對象的擴展
-
Array.from()
用于將兩類對象轉為真正的數(shù)組:類似數(shù)組的對象(array-like object
)和可遍歷(iterable
)的對象(包括ES6
新增的數(shù)據(jù)結構Set
和Map
)究反。Array.from('foo') // ["f", "o", "o"] // 擴展運算符(...)也可以將某些數(shù)據(jù)結構轉為數(shù)組 [ ...document.querySelectorAll('div') ] // NodeList對象 Array.from({ length: 3 }) // [ undefined, undefined, undefined ] Array.from([1, 2, 3], x => x + x) // [2, 4, 6]
-
Array.of()
:用于將一組值寻定,轉換為數(shù)組Array.of() // [] Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1 // 這個方法的主要目的,是彌補數(shù)組構造函數(shù)Array()的不足精耐。因為參數(shù)個數(shù)的不同狼速,會導致Array()的行為有差異。 Array() // [] Array(7) // [empty, empty, empty, empty, empty, empty] Array(3, 11, 8) // [3, 11, 8]
-
數(shù)組實例的
copyWithin()
在當前數(shù)組內部卦停,將指定位置的成員復制到其他位置(會覆蓋原有成員)向胡,然后返回當前數(shù)組,會修改當前數(shù)組惊完。
Array.prototype.copyWithin(target, start = 0, end = this.length)
它接受三個參數(shù)僵芹。這三個參數(shù)都應該是數(shù)值,如果不是小槐,會自動轉為數(shù)值拇派。- target(必需):從該位置開始替換數(shù)據(jù)。
- start(可選):從該位置開始讀取數(shù)據(jù)凿跳,默認為0件豌。如果為負值,表示倒數(shù)控嗜。
- end(可選):到該位置前停止讀取數(shù)據(jù)茧彤,默認等于數(shù)組長度。如果為負值疆栏,表示倒數(shù)曾掂。
['a', 'b', 'c', 'd', 'e'].copyWithin(0, 3, 4) // ["d", "b", "c", "d", "e"] [1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5] [1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5]
數(shù)組實例的
find() 和 findIndex()
-
數(shù)組實例的
fill()
:fill
方法使用給定值惫谤,填充一個數(shù)組['a', 'b', 'c'].fill(7) // [7, 7, 7] new Array(3).fill(7) // [7, 7, 7] // 可以接受第二個和第三個參數(shù),用于指定填充的起始位置和結束位置 ['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c'] [1, 2, 3, 4].fill(5, 1) // [1, 5, 5, 5]
-
數(shù)組實例的
entries()遭殉,keys() 和 values()
/* * 用于遍歷數(shù)組石挂,都返回一個遍歷器對象,可以用 for...of 循環(huán)進行遍歷 * 唯一的區(qū)別是 keys() 是對鍵名的遍歷险污、values() 是對鍵值的遍歷痹愚、entries() 是對鍵值對的遍歷 */ for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"
數(shù)組的空位:明確將空位轉為
undefined
-
ES7(ES2016)
-
數(shù)組實例的
includes()
返回一個布爾值,表示某個數(shù)組是否包含給定的值蛔糯,與字符串的includes
方法類似[1, 2, 3].includes(2); // true [1, 2, 3].includes(4); // false [1, 2, NaN].includes(NaN); // true
該方法的第二個參數(shù)表示搜索的起始位置拯腮,默認為0。如果第二個參數(shù)為負數(shù)蚁飒,則表示倒數(shù)的位置动壤,如果這時它大于數(shù)組長度(比如第二個參數(shù)為-4,但數(shù)組長度為3)淮逻,則會重置為從0開始琼懊。
[1, 2, 3].includes(3, 3); // false [1, 2, 3].includes(3, -1); // true
另外,
Map
和Set
數(shù)據(jù)結構有一個has
方法爬早,需要注意與includes
區(qū)分哼丈。
1.Map
結構的has方法,是用來查找鍵名的筛严,比如Map.prototype.has(key)醉旦、WeakMap.prototype.has(key)、Reflect.has(target, propertyKey)
桨啃。
2.Set
結構的has
方法车胡,是用來查找值的,比如Set.prototype.has(value)照瘾、WeakSet.prototype.has(value)
匈棘。 -
冪運算符
**
console.log(2**10) // 1024 console.log(Math.pow(2, 10)) // 1024
-
模板字符串(Template string)
自ES7
起,帶標簽的模版字面量遵守以下轉義序列的規(guī)則:-
Unicode
字符以"\u"
開頭析命,例如\u00A9
-
Unicode
碼位用"\u{}"表示主卫,例如\u{2F804}
- 十六進制以
"\x"
開頭,例如\xA9
- 八進制以
""
和數(shù)字開頭碳却,例如\251
-
ES8(ES2017)
-
async / await
Promise 的語法糖,專門解決回調地獄笑旺,async 函數(shù)返回一個 Promise 對象昼浦。async 函數(shù)內部 return 語句返回的值,會成為 then 方法回調函數(shù)的參數(shù)筒主。async function f() { return 'hello world'; } f().then(v => console.log(v)) // "hello world" // 同時觸發(fā)寫法 let [foo, bar] = await Promise.all([getFoo(), getBar()]);
-
Object.values():返回一個給定對象自身的所有可枚舉屬性值的數(shù)組
const object1 = { a: 'somestring', b: 42, c: false } console.log(Object.values(object1)) // ["somestring", 42, false]
-
Object.entries():返回一個給定對象自身可枚舉屬性的鍵值對數(shù)組
const object1 = { a: 'somestring', b: 42 } console.log(Object.entries(object1)) // [["a","somestring"],["b",42]] for (let [key, value] of Object.entries(object1)) { console.log(`${key}: ${value}`) } // "a: somestring" // "b: 42"
-
padStart():用另一個字符串填充當前字符串(重復关噪,如果需要的話)鸟蟹,以便產(chǎn)生的字符串達到給定的長度。填充從當前字符串的開始(左側)應用的使兔。
const str1 = '5' console.log(str1.padStart(4, '0')) // "0005" // 若無第二個參數(shù)建钥,用空格填充 console.log(str1.padStart(4)) // " 5"
-
padEnd():用一個字符串填充當前字符串(如果需要的話則重復填充),返回填充后達到指定長度的字符串虐沥。從當前字符串的末尾(右側)開始填充熊经。
const str1 = 'Breaded Mushrooms' console.log(str1.padEnd(25, '.')) // "Breaded Mushrooms........" const str2 = '200' console.log(str2.padEnd(5)) // "200 "
函數(shù)參數(shù)結尾逗號
-
SharedArrayBuffer對象
SharedArrayBuffer
對象用來表示一個通用的,固定長度的原始二進制數(shù)據(jù)緩沖區(qū)欲险,類似于ArrayBuffer
對象镐依,它們都可以用來在共享內存(shared memory
)上創(chuàng)建視圖。與ArrayBuffer
不同的是天试,SharedArrayBuffer
不能被分離槐壳。// 參數(shù)length指所創(chuàng)建的數(shù)組緩沖區(qū)的大小,以字節(jié)(byte)為單位 let sab = new SharedArrayBuffer(1024) // 創(chuàng)建一個1024字節(jié)的緩沖
-
Atomics對象
Atomics對象
提供了一組靜態(tài)方法用來對SharedArrayBuffer
對象進行原子操作喜每。-
Atomics.add()
:將指定位置上的數(shù)組元素與給定的值相加务唐,并返回相加前該元素的值。 -
Atomics.and()
:將指定位置上的數(shù)組元素與給定的值相與,并返回與操作前該元素的值哨鸭。 -
Atomics.compareExchange()
:如果數(shù)組中指定的元素與給定的值相等徒河,則將其更新為新的值,并返回該元素原先的值崇堰。 -
Atomics.exchange()
:將數(shù)組中指定的元素更新為給定的值,并返回該元素更新前的值涩咖。 -
Atomics.load()
:返回數(shù)組中指定元素的值海诲。 -
Atomics.or()
:將指定位置上的數(shù)組元素與給定的值相或,并返回或操作前該元素的值檩互。 -
Atomics.store()
:將數(shù)組中指定的元素設置為給定的值特幔,并返回該值。 -
Atomics.sub()
:將指定位置上的數(shù)組元素與給定的值相減闸昨,并返回相減前該元素的值蚯斯。 -
Atomics.xor()
:將指定位置上的數(shù)組元素與給定的值相異或,并返回異或操作前該元素的值饵较。 -
Atomics.wait()
:檢測數(shù)組中某個指定位置上的值是否仍然是給定值拍嵌,是則保持掛起直到被喚醒或超時。返回值為 “ok”循诉、“not-equal” 或 “time-out”横辆。調用時,如果當前線程不允許阻塞茄猫,則會拋出異常(大多數(shù)瀏覽器都不允許在主線程中調用 wait())狈蚤。 -
Atomics.wake()
:喚醒等待隊列中正在數(shù)組指定位置的元素上等待的線程困肩。返回值為成功喚醒的線程數(shù)量。 -
Atomics.isLockFree(size)
:可以用來檢測當前系統(tǒng)是否支持硬件級的原子操作脆侮。對于指定大小的數(shù)組锌畸,如果當前系統(tǒng)支持硬件級的原子操作,則返回 true靖避;否則就意味著對于該數(shù)組潭枣,Atomics 對象中的各原子操作都只能用鎖來實現(xiàn)。此函數(shù)面向的是技術專家筋蓖。
-
-
Object.getOwnPropertyDescriptors():用來獲取一個對象的所有自身屬性的描述符
const obj = { foo: 123, get bar() { return 'abc' } }; Object.getOwnPropertyDescriptors(obj) // { foo: // { value: 123, // writable: true, // enumerable: true, // configurable: true }, // bar: // { get: [Function: bar], // set: undefined, // enumerable: true, // configurable: true } }
-
淺拷貝一個對象
Object.assign()
方法只能拷貝源對象的可枚舉的自身屬性卸耘,同時拷貝時無法拷貝屬性的特性們,而且訪問器屬性會被轉換成數(shù)據(jù)屬性粘咖,也無法拷貝源對象的原型蚣抗,該方法配合Object.create()
方法可以實現(xiàn)上面說的這些。Object.create( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) );
-
創(chuàng)建子類
創(chuàng)建子類的典型方法是定義子類翰铡,將其原型設置為超類的實例漠秋,然后在該實例上定義屬性求晶。這么寫很不優(yōu)雅,特別是對于 getters 和 setter 而言。 相反,您可以使用此代碼設置原型:function superclass() {} superclass.prototype = { // 在這里定義方法和屬性 }; function subclass() {} subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({ // 在這里定義方法和屬性 }));
-
ES9(ES2018)
-
for await…of
for await...of
語句創(chuàng)建一個循環(huán),該循環(huán)遍歷異步可迭代對象以及同步可迭代對象,包括: 內置的String
,Array
,類似數(shù)組對象 (例如arguments
或NodeList
)苞尝,TypedArray
,Map
,Set
和用戶定義的異步/同步迭代器恬涧。其會調用自定義迭代鉤子注益,并為每個不同屬性的值執(zhí)行語句。async function* asyncGenerator() { var i = 0 while (i < 3) { yield i++ } } (async function() { for await (num of asyncGenerator()) { console.log(num) } })() // 0 // 1 // 2
模板字符串(Template string)
ES9
開始溯捆,模板字符串允許嵌套支持常見轉義序列丑搔,移除對ECMAScript
在帶標簽的模版字符串中轉義序列的語法限制。-
正則表達式 Unicode 轉義
正則表達式中的Unicode
轉義符允許根據(jù)Unicode
字符屬性匹配Unicode
字符提揍。 它允許區(qū)分字符類型低匙,例如大寫和小寫字母,數(shù)學符號和標點符號碳锈。// 匹配所有數(shù)字 const regex = /^\p{Number}+$/u; regex.test('231???') // true regex.test('???') // true regex.test('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ') // true // 匹配所有空格 \p{White_Space} // 匹配各種文字的所有字母顽冶,等同于 Unicode 版的 \w [\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}] // 匹配各種文字的所有非字母的字符,等同于 Unicode 版的 \W [^\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}] // 匹配 Emoji /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu // 匹配所有的箭頭字符 const regexArrows = /^\p{Block=Arrows}+$/u; regexArrows.test('←↑→↓?????????????') // true
-
正則表達式 s/dotAll 模式
JS
正則增加了一個新的標志s
用來表示dotAll
售碳,這可以匹配任意字符强重。const re = /foo.bar/s; // 等價于 const re = new RegExp('foo.bar', 's'); re.test('foo\nbar'); // true re.dotAll; // true re.flags; // "s"
具名組匹配
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
對象擴展操作符
Promise.prototype.finally()
finally()
方法會返回一個Promise
,當promise
的狀態(tài)變更间景,不管是變成rejected
或者fulfilled
,最終都會執(zhí)行finally()
的回調封拧。
fetch(url)
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
.finally(() => {
console.log('結束')
})
ES10(ES2019)
- 數(shù)組實例的
flat()
用于將嵌套的數(shù)組“拉平”,變成一維的數(shù)組捧杉。該方法返回一個新數(shù)組评甜,對原數(shù)據(jù)沒有影響蜕着。參數(shù)depth
表示要提取嵌套數(shù)組的結構深度蓖乘,默認值為 1零聚。
console.log([1 ,[2, 3]].flat()); // [1, 2, 3]
// 指定轉換的嵌套層數(shù)
console.log([1, [2, [3, [4, 5]]]].flat(2)); // [1, 2, 3, [4, 5]]
// 不管嵌套多少層【使用 Infinity 作為深度,展開任意深度的嵌套數(shù)組】
console.log([1, [2, [3, [4, 5]]]].flat(Infinity)); // [1, 2, 3, 4, 5]
// 自動跳過空位【會移除數(shù)組中的空項】
console.log([1, [2, , 3]].flat()); // [1, 2, 3]
// 傳入 <=0 的整數(shù)將返回原數(shù)組蚂会,不“拉平”
console.log([1, [2, [3, [4, 5]]]].flat(0)); // [1, [2, [3, [4, 5]]]]
console.log([1, [2, [3, [4, 5]]]].flat(-10)); // [1, [2, [3, [4, 5]]]]
- 數(shù)組實例的
flatMap()
首先使用映射函數(shù)映射每個元素,然后將結果壓縮成一個新數(shù)組。它與map
和連著深度值為1的flat
幾乎相同余指,但flatMap
通常在合并成一種方法的效率稍微高一些。
[1, 2, 3, 4].flatMap(x => x * 2); // [2, 4, 6, 8]
[1, 2, 3, 4].flatMap(x => [x * 2]); // [2, 4, 6, 8]
[1, 2, 3, 4].flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]
[1, 2, 3, 4].map(x => [x * 2]); // [[2], [4], [6], [8]]
字符串實例的
trimStart() / trimLeft() / trimEnd() / trimRight()
去除字符首或尾的空格,trimStart()
跟trimEnd()
才是標準方法足丢,trimLeft()
跟trimRight()
只是別名Object.fromEntries()
把鍵值對列表轉換為一個對象斩跌,它是Object.entries()
的反函數(shù)。
const entries = new Map([
['foo', 'bar'],
['baz', 42]
])
console.log(Object.fromEntries(entries)) // Object { foo: "bar", baz: 42 }
-
Symbol.prototype.description
通過工廠函數(shù)Symbol()
創(chuàng)建符號時,您可以選擇通過參數(shù)提供字符串作為描述:
Symbol('desc').toString(); // "Symbol(desc)"
Symbol('desc').description; // "desc"
Symbol('').description; // ""
Symbol().description; // undefined
//全局 symbols
Symbol.for('foo').toString(); // "Symbol(foo)"
Symbol.for('foo').description; // "foo"
Function.prototype.toString()
現(xiàn)在返回精確字符洛姑,包括空格和注釋try-catch
catch
的參數(shù)可省略
ES11(ES2020)
-
String.prototype.matchAll
返回一個包含所有匹配正則表達式及分組捕獲結果的迭代器。
var regexp = /t(e)(st(\d?))/g
var str = 'test1test2'
str.match(regexp) // ['test1', 'test2']
str.matchAll(regexp) // RegExpStringIterator {}
[...str.matchAll(regexp)] // [ ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4], ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4] ]
- 動態(tài)
import()
const modelpath = '/demo'
import(`@/pages${modelpath}`).then(module => {}).catch(err => {})
import.meta
import.meta
會返回一個對象,有一個url
屬性两入,返回當前模塊的url
路徑,只能在模塊內部使用。export * as XX from 'module'
和import * as XX from 'module'
Promise.allSettled()
Promise.allSettled
方法返回一個在所有給定的promise
都已經(jīng)fulfilled
或rejected
后的promise
她我,并帶有一個對象數(shù)組矾踱,每個對象表示對應的promise
結果呛讲。BigInt
現(xiàn)在的基本數(shù)據(jù)類型(值類型)不止5種(ES6之后是六種)了哦芽偏!加上BigInt
一共有七種基本數(shù)據(jù)類型,分別是:String、Number、Boolean、Null、Undefined、Symbol、BigInt
BigInt
可以表示任意大的整數(shù)堆缘÷槌担可以用在一個整數(shù)字面量后面加n
的方式定義一個BigInt
,如:10n免钻,或者調用函數(shù)BigInt()
握童。globalThis
指向全局對象稽揭,瀏覽器下指向window
可選鏈操作符(?.)
info.animal?.reptile?.tortoise
空值合并操作符(??)
當左側的操作數(shù)為null
或者undefined
時步鉴,返回其右側操作數(shù)阳似,否則返回左側操作數(shù)。
與邏輯或操作符(||
)不同,邏輯或操作符會在左側操作數(shù)為假值時返回右側操作數(shù)青自。
const foo = null ?? 'default string';
console.log(foo); // "default string"
const baz = 0 ?? 42;
console.log(baz); // 0
ES12(ES2021)(預計將在2021年年中發(fā)布)
-
String.prototype.replaceAll
replaceAll
返回一個全新的字符串伙单,所有符合匹配規(guī)則的字符都將被替換掉吻育,替換規(guī)則可以是字符串或者正則表達式。
let string = 'I like 前端,I like 前端公蝦米'
console.log(string.replace(/like/g,'love')) // 'I love 前端,I love 前端公蝦米'
console.log(string.replaceAll('like','love')) // 'I love 前端,I love 前端公蝦米'
需要注意的是淤井,
replaceAll
在使用正則表達式的時候布疼,如果非全局匹配(/g
),則replaceAll()
會拋出一個異常
console.log(string.replaceAll(/like/,'love')) // TypeError
Promise.any
當Promise
列表中的任意一個promise
成功resolve
則返回第一個resolve
的結果狀態(tài)币狠,如果所有的promise
均reject
游两,則拋出異常表示所有請求失敗。
Promise.race
一旦某個promise
觸發(fā)了resolve
或者reject
漩绵,就直接返回了該狀態(tài)結果贱案,并不在乎其成功或者失敗。WeakRefs
當我們通過(const止吐、let宝踪、var
)創(chuàng)建一個變量時,垃圾收集器GC
將永遠不會從內存中刪除該變量碍扔,只要它的引用仍然存在可訪問瘩燥。WeakRef
對象包含對對象的弱引用。對對象的弱引用是不會阻止垃圾收集器GC
恢復該對象的引用蕴忆,則GC
可以在任何時候刪除它颤芬。
WeakRefs
在很多情況下都很有用悲幅,比如使用Map
對象來實現(xiàn)具有很多需要大量內存的鍵值緩存套鹅,在這種情況下最方便的就是盡快釋放鍵值對占用的內存。
目前汰具,可以通過WeakMap()
或者WeakSet()
來使用WeakRefs
卓鹿。邏輯運算符和賦值表達式
表達式a op= b
等同于a = a op (a = b)
a ||= b
//等價于
a = a || (a = b) // 當LHS值不存在時,將RHS變量賦值給LHS
a &&= b
//等價于
a = a && (a = b) // 當LHS值存在時留荔,將RHS變量賦值給LHS
a ??= b
//等價于
a = a ?? (a = b) // 當LHS值為null或者undefined時吟孙,將RHS變量賦值給LHS
- 數(shù)字分隔符號
數(shù)字分隔符,可以在數(shù)字之間創(chuàng)建可視化分隔符聚蝶,通過_
下劃線來分割數(shù)字杰妓,使數(shù)字更具可讀性
const money = 1_000_000_000
//等價于
const money = 1000000000
const totalFee = 1000.12_34
//等價于
const totalFee = 1000.1234
// 該新特性同樣支持在八進制數(shù)中使用
const number = 0o123_456
//等價于
const number = 0o123456