ES6-ES12
目錄
- ES6
- 一、class定義類
- 1.類的聲明
- 2.constructor
- 3.實例方法
- 4.類的訪問器方法
- 5.類的靜態方法
- 6.繼承
- 7.super關鍵字
- 二、字面量的增強
- 1.屬性的簡寫
- 2.方法的簡寫
- 3.計算屬性名
- 三、解構賦值
- 1.數組的解構
- 2.對象的解構
- 四、var、const、let
- 1.var
- 2.const
- 3.let
- 五、模板字符串
- 1.基本使用
- 2.標簽模板字符串
- 六、函數的參數
- 1.函數的默認參數
- 2.函數的剩余參數
- 3.箭頭函數的補充
- 七、展開運算符
- 八、數值的表示
- 九、Symbol
- 1.Symbol的使用
- 十、Set
- 1.Set的基本使用
- 2.Set的常見方法
- 3.WeakSet
- (1) Set與WeakSet的區別
- (2) WeakSet常見方法
- 十一、Map
- 1.Map的常用方法
- 2.WeakMap
- (1)Map與WeakMap的區別
- (2)WeakMap的常用方法
- (3)WeakMap的應用
- 十二、Porxy
- 1.監聽對象的方式
- 2.Proxy的基本使用
- 3.Proxy的捕獲器
- 十三、Reflect
- 1.Reflect的基本使用
- 2.Reflect的常見方法
- 3.Reflect中的construct
- 4.receiver的作用
- ES7
- 1.數組includes方法
- 2.指數運算符
- ES8
- 1. Object values
- 2. Object entries
- 3.String Padding
- 4.Trailing Commas
- 5.Object Descriptors
- ES9
- 一、迭代器iterators
- 二、promise的finally
- ES10
- 1.flat與flatMap
- (1)flat
- (2)flatMap
- 2.entries轉對象
- 3.trimStart與trimEnd
- 4. Symbol description
- 5. Optional catch binding
- ES11
- 1.BigInt
- 2.空值合并運算符
- 3.可選鏈
- 4.globalThis
- ES12
- 1.FinalizationRegistry
- 2.WeakRefs
ES6
一、class定義類
構造函數形式創建 類,不僅僅和編寫普通的函數過于相似,而且代碼并不容易理解。 在ES6新的標準中使用了class關鍵字來直接定義類; 但是類本質上構造函數、原型鏈的語法糖而已;
1.類的聲明
// 類聲明 class Person { } // 類表達式 var Student = class { }// 相似的如: // 函數聲明 function Parent() { } // 函數表達式 var son = function() { }2.constructor
constructor方法(即構造方法)是類的默認方法,通過new生成對象時,自動調用該方法。
注:
-
每個類只能有一個構造函數,如果包含多個構造函數,那么會拋出異常;
-
一個類必須有constructor方法,如果沒有顯示定義,一個空的constructor方法會被默認添加;
3.實例方法
class中定義的方法,實際上都是定義在這個"類"的prototype上的。
class People {constructor(name, age) {this.name = namethis.age = age}eatting() {console.log(this.name + "吃!");}running() {console.log(this.name + "跑!");} }console.log(Object.getOwnPropertyDescriptors(People)); // 輸出如下: // { // length: { value: 2, writable: false, enumerable: false, configurable: true }, // name: { // value: 'People', // writable: false, // enumerable: false, // configurable: true // }, // prototype: { // value: {}, // writable: false, // enumerable: false, // configurable: false // } // } console.log(Object.getOwnPropertyDescriptors(People.prototype)); // 輸出如下: // { // constructor: { // value: [class People], // writable: true, // enumerable: false, // configurable: true // }, // eatting: { // value: [Function: eatting], // writable: true, // enumerable: false, // configurable: true // }, // running: { // value: [Function: running], // writable: true, // enumerable: false, // configurable: true // } // }4.類的訪問器方法
當調用獲取或設置某個屬性時,觸發get或set函數里的函數體代碼。
class Abc {constructor(name) {this.name = name}set name(newName) {console.log("設置了這個屬性name");}get name() {console.log("調用或獲取了這個屬性name");// return this.namereturn "獲取" // get必須有返回值} } console.log(Abc.name); // Abc5.類的靜態方法
靜態方法通常用于定義直接使用類來執行的方法,不需要有類的實例,使用static關鍵字來定義.
class Asd {constructor(asd) {this.asd = asd}haox() {console.log("不是靜態方法不可以直接調用");}static create() {console.log("你調用了靜態方法");} } Asd.create() // 你調用了靜態方法 // Asd.haoX() // 報錯,不是靜態方法不能直接調用,需要new一個實例才能調用 var a1 = new Asd() a1.haox() // 不是靜態方法不可以直接調用6.繼承
通過extends關鍵字繼承。
class A {} class B extends A {}- 子類中新添加的方法是添加到了子類的原型對象上,并不是父類的遠程對象上;
7.super關鍵字
- 可調用父類的構造函數;
- 可調用父類上的方法
二、字面量的增強
ES6中對 對象字面量 進行了增強;
1.屬性的簡寫
2.方法的簡寫
3.計算屬性名
var age = 18 var obj1 = {// age : ageage, // 1.屬性的簡寫// 2.方法名簡寫// foo: function() {// }foo() { // 簡寫},// 3.計算屬性[age + 123]: 'hhhhh',[age + '123']: 'hhhhh' }console.log(obj1); // { '141': 'hhhhh', '18123': 'hhhhh', age: 18, foo: [Function: foo] }三、解構賦值
1.數組的解構
// 1.數組的解構 var names = ['agc', 'cag', 'asd'] var [item1, item2, item3] = names console.log(item1,item2,item3); // agc cag asd// 2.解構后面元素 var [, itema, itemb] = names console.log(itema,itemb); // cag asd// 3.解構出一個元素,后面的元素放到一個新數組中 var [itemx, ...newNames] = names console.log(newNames); // [ 'cag', 'asd' ]// 4.解構的默認值 (當解構的元素可能沒有值時,可以設置一個默認值) var [itema, itemb, itemc, itemd = 'aaa'] = names console.log(itemd); // aaa2.對象的解構
var obj = {name: 'tjx',age: 39,height: 12,a: 12 }// 1.對象的解構 var { namea, age, height } = obj console.log(namea, age, height); // tjx 39 12var { a } = obj console.log(a); // 12// 2.解構重命名 var {name: newName} = obj console.log(newName); // tjx// 3.解構重命名并給默認值 var { address: newAddress = "廣州" } = obj console.log(newAddress); // 廣州四、var、const、let
-
let和const,是目前開發中推薦使用的;
-
優先推薦使用const,這樣可以保證數據的安全性不會被隨意的篡改;
-
只有當明確知道一個變量后續會需要被重新賦值時,這個時候再使用let;
1.var
- 作用域提升;
- 函數有塊級作用域,在函數中var變量屬于該函數的局部變量;
2.const
const關鍵字是constant的單詞的縮寫,表示常量、衡量的意思;
它表示保存的數據一旦被賦值,就不能被修改;
但是如果賦值的是引用類型,那么可以通過引用找到對應的對象,修改對象的內容;
3.let
聲明的變量具有塊級作用域的特征;
五、模板字符串
1.基本使用
let agea = 9 const info = `age: ${agea *2}` console.log(info); // age: 18function doubleAge() {return agea * 2 } const infoa = `age: ${doubleAge()}` console.log(infoa); // age: 182.標簽模板字符串
// 第一個參數依然是模板字符串中整個字符串,只是被切割成多塊,放到了一個數組中 // 第二個參數是模塊字符串中,第一個${},一次類推 function foo(m, n, x) {console.log(m,n, x, '..........'); } const named = 'tjx' const aged = 13// 通過模板標簽調用函數 foo`Hello${named}, world${aged},!` // [ 'Hello', ', world', ',!' ] tjx 13 ..........六、函數的參數
1.函數的默認參數
// 1.函數默認參數 function foo(m = 'aaa', n = 'bb') {console.log(m,n); } foo() // aaa bb foo('dfs','fds') // dfs fds// 對象參數和默認參數以及解構 // 寫法一: function printInfo({name, age} = {name: 'tjc', age: 19}) {console.log(name,age); } printInfo() // tjc 19 printInfo({name: 'lobe', age: 90}) // lobe 90// 寫法二: function printInfo({name = 'tjx', age = 19} = {}) {console.log(name,age); }2.函數的剩余參數
function foo(m,n,...args) {console.log(m,n); // 1 2console.log(args); // [ 3, 4, 5, 6, 7 ]console.log(arguments); // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7 } } foo(1,2,3,4,5,6,7)3.箭頭函數的補充
- 箭頭函數沒有prototype,不能通過new關鍵字創建箭頭函數;
- 箭頭函數沒有this以及arguments
七、展開運算符
const nameg = ['asd', 'dfg', 'sdfg'] const nameh = 'tjx' const infog = {name: 'tjx', age: 19}// 1.函數調用時 function foo(x, y, z) {console.log(x,y,z); }foo(...nameg) // asd dfg sdfg foo(...nameh) // t j x// 2.構造數組時 const newNameg = [...nameg, ...nameh] console.log(newNameg); // [ 'asd', 'dfg', 'sdfg', 't', 'j', 'x' ]// 3.構造對象字面量時 const objh = {...infog, address: 'guand'} console.log(objh); // { name: 'tjx', age: 19, address: 'guand' }八、數值的表示
const num1 = 100 // 十進制 const num2 = 0b100 // 二進制 const num3 = 0o100 // 八進制 const num4 = 0x100 // 十六進制console.log(num1, num2, num3, num4); // 100 4 64 256// 大的數值的連接符 const num = 10_000_000_000_000 console.log(num); // 10000000000000九、Symbol
在ES6之前,對象的屬性名都是字符串形式,那么很容易造成屬性名的沖突; 比如原來有一個對象,我們希望在其中添加一個新的屬性和值,但是我們在不確定它原來內部有什么內容的情況下, 很容易造成沖突,從而覆蓋掉它內部的某個屬性;Symbol就是為了解決上面的問題,用來生成一個獨一無二的值。
1.Symbol的使用
- Symbol值是通過Symbol函數來生成的,生成后可以作為屬性名; 在ES6中,對象的屬性名可以使用字符串,也可以使用Symbol值;
- Symbol即使多次創建值,它們也是不同的:Symbol函數執行后每次創建出來的值都是獨一無二的;
- 也可以在創建Symbol值的時候傳入一個描述description:這個是(ES10)新增的特性;
十、Set
1.Set的基本使用
在ES6中新增了另外兩種數據結構:Set、Map,以及它們的另外形式WeakSet、WeakMap。
- Set是一個新增的數據結構,可以用來保存數據,類似于數組,但是和數組的區別是元素不能重復。
- 創建Set我們需要通過Set構造函數(暫時沒有字面量創建的方式)
2.Set的常見方法
Set常見屬性:
- size:返回Set中的元素的個數;
Set常見方法:
- add(value):添加某個元素,返回Set對象本身;
- delete(value):從set中刪除和這個值相等的元素,返回boolean類型;
- has(value):判斷set中是否存在某個元素,返回boolean類型;
- clear():清空set中所有的元素,沒有返回值;
- forEach(callback, [, thisArg]):通過forEach遍歷set;
**另外:**Set是支持for of的遍歷的。
const arr1 = [33, 10, 26, 30, 33, 26] const arrSet1 = new Set(arr1)// 1.set的屬性 size console.log(arrSet1.size); // 4// 2.set的方法 arrSet1.add(1000) console.log(arrSet1); // Set(5) { 33, 10, 26, 30, 1000 }arrSet1.delete(1000) // 刪除這里只能傳入值,不是下標 console.log(arrSet1); // Set(4) { 33, 10, 26, 30 }console.log(arrSet1.has(33)); // true 判斷是否有這個值,返回布爾值arrSet1.clear() console.log(arrSet1); // Set(0) {}// 遍歷Set const arr2 = [33, 10, 26, 30, 33, 26] const arrSet2 = new Set(arr2)arrSet2.forEach(item => {console.log(item); })for (const item of arrSet2) {console.log(item); }3.WeakSet
一般比較少用。
(1) Set與WeakSet的區別
- 區別一:WeakSet中只能存放對象類型,不能存放基本數據類型;
- 區別二:WeakSet對元素的引用是弱引用,如果沒有其他引用對某個對象進行引用,那么GC可以對該對象進行回收;
(2) WeakSet常見方法
- add(value):添加某個元素,返回WeakSet對象本身;
- delete(value):從WeakSet中刪除和這個值相等的元素,返回boolean類型;
- has(value):判斷WeakSet中是否存在某個元素,返回boolean類型;
注意:WeakSet只是對對象的弱引用,如果我們遍歷獲取到其中的元素,那么有可能造成對象不能正常的銷毀。 所以存儲到WeakSet中的對象是沒辦法獲取的;
十一、Map
數據結構是Map,用于存儲映射關系。
對象存儲映射關系只能用字符串(ES6新增了Symbol)作為屬性名(key);
某些情況下我們可能希望通過其他類型作為key,比如對象,這是我們可以使用Map。
1.Map的常用方法
- size:返回Map中元素的個數;
- set(key, value):在Map中添加key、value,并且返回整個Map對象;
- get(key):根據key獲取Map中的value; phas(key):判斷是否包括某一個key,返回Boolean類型;
- delete(key):根據key刪除一個鍵值對,返回Boolean類型;
- clear():清空所有的元素;
- forEach(callback, [, thisArg]):通過forEach遍歷Map;
另外:
- Map也可以通過for of進行遍歷。
2.WeakMap
(1)Map與WeakMap的區別
- 區別一:WeakMap的key只能使用對象,不接受其他的類型作為key;
- 區別二:WeakMap的key對對象想的引用是弱引用,如果沒有其他引用引用這個對象,那么GC可以回收該對象;
(2)WeakMap的常用方法
- set(key, value):在Map中添加key、value,并且返回整個Map對象;
- get(key):根據key獲取Map中的value;
- has(key):判斷是否包括某一個key,返回Boolean類型;
- delete(key):根據key刪除一個鍵值對,返回Boolean類型;
(3)WeakMap的應用
vue3響應式原理。
// 引用場景(vue3響應式原理) const obj1 = {name: 'tjx',age: 19 } function obj1NameFn1() {console.log("obj1NameFn1被執行"); } function obj1NameFn2() {console.log("obj1NameFn2被執行"); } function obj1AgeFn1() {console.log("obj1AgeFn1被執行"); } function obj1AgeFn2() {console.log("obj1AgeFn2被執行"); }const obj3 = {name: 'aaa',age: 09 } function obj3NameFn1() {console.log("obj3NameFn1被執行"); } function obj3NameFn2() {console.log("obj3NameFn2被執行"); }// 1.創建WealMap const weakMap = new WeakMap()// 2.收集依賴結構 // 2.1 對obj1收集的數據結構 const obj1Map = new Map() obj1Map.set('name', [obj1NameFn1, obj1NameFn2]) obj1Map.set('age', [obj1AgeFn1, obj1AgeFn2]) weakMap.set(obj1, obj1Map)// 3.如果obj1.name發生了變化 // Proxy/Object.definePoroperty obj1.name = 'java' const targetWeakMap = weakMap.get(obj1) const fns = targetWeakMap.get('name') fns.forEach(item => item())十二、Porxy
1.監聽對象的方式
通過Object.defineProperty的get和set監聽對象屬性的變化。
const obj = {name: 'tjx',age: 19 }Object.keys(obj).forEach(key => {let value = obj[key]Object.defineProperty(obj, key, {get: function() {console.log(`監聽到obj對象的${key}屬性被訪問`);return value},set: function(newValue) {console.log(`監聽到obj對象的${key}屬性被修改`);value = newValue}}) }) obj.name = 'kis' obj.age = 30console.log(obj.name); console.log(obj.age); // 傳統監聽方法的弊端,不能監聽新的屬性的添加 obj.height = 1.88缺點:如果監聽更加豐富的操作,比如新增屬性、刪除屬性,那么 Object.defineProperty是無能為力的。所以可以通過Proxy類。
2.Proxy的基本使用
在ES6中,新增了一個Proxy類,這個類用于幫助我們創建一個代理。先創建一個代理對象(Proxy對象);之后對該對象的所有操作,都通過代理對象來完成,代理對象可以監聽我們想要對原對象進行哪些操作;
- 首先new Proxy對象,傳入需要偵聽的對象以及一個處理對象;
- 在處理對象中進行監聽,之后的操作都是直接對Proxy的操作,而不是原有的對象;
3.Proxy的捕獲器
13個常用捕獲器。
- handler.getPrototypeOf()
-
- Object.getPrototypeOf 方法的捕捉器。
- handler.setPrototypeOf()
-
- Object.setPrototypeOf 方法的捕捉器。
- handler.isExtensible()
-
- Object.isExtensible 方法的捕捉器。
- handler.preventExtensions()
-
- Object.preventExtensions 方法的捕捉器。
- handler.getOwnPropertyDescriptor()
-
- Object.getOwnPropertyDescriptor 方法的捕捉器。
- handler.defineProperty()
-
- Object.defineProperty 方法的捕捉器。
- handler.ownKeys()
-
- Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。
- handler.has()
-
- in 操作符的捕捉器。
- handler.get()
- 屬性讀取操作的捕捉器。
- handler.set()
-
- 屬性設置操作的捕捉器。
- handler.deleteProperty()
-
- delete 操作符的捕捉器。
- handler.apply()
-
- 函數調用操作的捕捉器。
- handler.construct()
-
- new 操作符的捕捉器。
對函數對象的監聽:
function foo() {} const fooProxy = new Proxy(foo, {apply: function(target, thisArg, argArray) {console.log("對foo函數進行了apply調用");return target.apply(thisArg, argArray)},construct: function(target, argArray, newTarget) {console.log("對foo函數進行了new調用");return new target(...argArray)} }) fooProxy.apply({}, ['a','b']) new fooProxy('a','b')十三、Reflect
- Reflect也是ES6新增的一個API,它是一個對象,字面的意思是反射。
- 那么這個Reflect有什么用呢?
-
- 它主要提供了很多操作JavaScript對象的方法,有點像Object中操作對象的方法;
-
- 比如Reflect.getPrototypeOf(target)類似于Object.getPrototypeOf();
- 比如Reflect.defineProperty(target, propertyKey, attributes)類似于Object.defineProperty() ;
- 如果我們有Object可以做這些操作,那么為什么還需要有Reflect這樣的新增對象呢?
-
- 這是因為在早期的ECMA規范中沒有考慮到這種對 對象本身 的操作如何設計會更加規范,所以將這些API放到了Object上面;
- 但是Object作為一個構造函數,這些操作實際上放到它身上并不合適;
- 另外還包含一些類似于 in、delete操作符,讓JS看起來是會有一些奇怪的;
- 所以在ES6中新增了Reflect,讓我們這些操作都集中到了Reflect對象上;
- 那么Object和Reflect對象之間的API關系,可以參考MDN文檔: 比較 Reflect 和 Object 方法 - JavaScript | MDN (mozilla.org)
1.Reflect的基本使用
const obj = {name: 'tjx',age: 19 }const objProxy = new Proxy(obj, {get: function(target, key, reciver) {console.log("get");return Reflect.get(target, key)},set: function(target, key, newValue, receiver) {console.log("set");target[key] = newValue// target[key] = newValue 與通過Reflect.set的區別是:后者有返回布爾值,代表是設置成功const result = Reflect.set(target, key, newValue)if(result) {0} else {}} }) objProxy.name = 'dfs' console.log(objProxy.name);2.Reflect的常見方法
- Reflect.getPrototypeOf(target)
-
- 類似于 Object.getPrototypeOf()。
- Reflect.setPrototypeOf(target, prototype)
-
- 設置對象原型的函數. 返回一個 Boolean, 如果更新成功,則返 回true。
- Reflect.isExtensible(target)
-
- 類似于 Object.isExtensible()
- Reflect.preventExtensions(target)
-
- 類似于 Object.preventExtensions()。返回一個Boolean。
- Reflect.getOwnPropertyDescriptor(target, propertyKey)
-
- 類似于 Object.getOwnPropertyDescriptor()。如果對象中存在 該屬性,則返回對應的屬性描述符, 否則返回 undefined.
- Reflect.defineProperty(target, propertyKey, attributes)
-
- 和 Object.defineProperty() 類似。如果設置成功就會返回 true
- Reflect.ownKeys(target)
-
- 返回一個包含所有自身屬性(不包含繼承屬性)的數組。(類似于 Object.keys(), 但不會受enumerable影響).
- Reflect.has(target, propertyKey)
-
- 判斷一個對象是否存在某個屬性,和 in 運算符 的功能完全相同。
- Reflect.get(target, propertyKey[, receiver])
-
- 獲取對象身上某個屬性的值,類似于 target[name]。
- Reflect.set(target, propertyKey, value[, receiver])
-
- 將值分配給屬性的函數。返回一個Boolean,如果更新成功,則返回true。
- Reflect.deleteProperty(target, propertyKey)
-
- 作為函數的delete操作符,相當于執行 delete target[name]。
- Reflect.apply(target, thisArgument, argumentsList)
-
- 對一個函數進行調用操作,同時可以傳入一個數組作為調用參數。和 Function.prototype.apply() 功能類似。
- Reflect.construct(target, argumentsList[, newTarget])
-
- 對構造函數進行 new 操作,相當于執行 new target(…args)。
3.Reflect中的construct
// 作用:創建的一個對象,但是這個對象的方式是另一個對象的方法 function Students(name, age) {this.name = namethis.age = age } function Teachers() {} // 執行Students函數中的內容,但是創建出的對象是Teacher對象 const teachers = Reflect.construct(Students, ['saf', 'sf'], Teachers) console.log(teachers); // Teachers { name: 'saf', age: 'sf' } console.log(teachers.__proto__ === Teachers.prototype); // true4.receiver的作用
如果我們的源對象(obj)有setter、getter的訪問器屬性,那么可以通過receiver來改變里面的this;
const obj = {_name: 'ujx',get name() {return this._name // 傳遞了reveiver后這里的this指向objProxy},set name(newValue) {this._name = newValue} }const objProxy = new Proxy(obj, {get: function(target, key, receiver) {// reveiver 是創建出來的代理對象console.log("get方法別訪問---", key, receiver); return Reflect.get(target, key, receiver)},set: function(target, key, newValue, receiver) {console.log("set方法被訪問------",key);Reflect.set(target, key, newValue, receiver)} }) objProxy.name = 'ksafa' // 返回了兩次 set方法被調用---- 但是兩次key值不同,第一次為name,第二次為_nameES7
1.數組includes方法
在ES7之前,如果我們想判斷一個數組中是否包含某個元素,需要通過 indexOf 獲取結果,并且判斷是否為 -1。
在ES7中,我們可以通過includes來判斷一個數組中是否包含一個指定的元素,根據情況,如果包含則返回 true, 否則返回false。
const arrays = ['aba', 'cag', 'aba', 'dca', NaN] if (arrays.indexOf('aba') !== -1) {console.log("包含aba"); // 包含aba }// ES7 console.log(arrays.includes('aba')); // true console.log(arrays.includes('aba', 3)); // false 第二個參數表示從第幾個開始查找是否包含該元素// includes與indexof的區別: indexOf不能查找NaN console.log(arrays.indexOf(NaN)); // -1 console.log(arrays.includes(NaN)); // true2.指數運算符
const result = Math.pow(3,3) const result2 = 3 ** 3 console.log(result, result2); // 27 27ES8
1. Object values
之前我們可以通過 Object.keys 獲取一個對象所有的key,在ES8中提供了 Object.values 來獲取所有的value值。
const obj = {name: 'tjx',age: 18 }console.log(Object.keys(obj)); // [ 'name', 'age' ] console.log(Object.values(obj)); // [ 'tjx', 18 ] // 用到非常少 console.log(Object.values(['abc', 'dxa', 'dsx'])); // [ 'abc', 'dxa', 'dsx' ] console.log(Object.values("abx")); // [ 'a', 'b', 'x' ]2. Object entries
通過Object.entries 可以獲取到一個數組,數組中會存放可枚舉屬性的鍵值對數組。
const obj = {name: 'tjx',age: 18 }console.log(Object.entries(obj)); // [ [ 'name', 'tjx' ], [ 'age', 18 ] ] const objEntries = Object.entries(obj) objEntries.forEach(item => {console.log(item[0], item[1]); })console.log(Object.entries(['abc', 'sgc', 'aej'])); // [ [ '0', 'abc' ], [ '1', 'sgc' ], [ '2', 'aej' ] ] console.log(Object.entries('adc')); // [ [ '0', 'a' ], [ '1', 'd' ], [ '2', 'c' ] ]3.String Padding
ES8中增加了 padStart 和 padEnd 方法,分 別是對字符串的首尾進行填充的。
const message = "hello world"const newMessage = message.padStart(15, '*').padEnd(20, '-') console.log(newMessage); // ****hello world-----// 案例:銀行卡位數的隱藏 const cardNumber = "52208420390323232" const lastFourCard = cardNumber.slice(-4) const finalCard = lastFourCard.padStart(cardNumber.length, '*') console.log(finalCard); // *************32324.Trailing Commas
在ES8中,我們允許在函數定義和調用時多加一個逗號。
function foo(a,b,) {console.log(a,b); } foo(10,20,)5.Object Descriptors
n ES8中增加了另一個對對象的操作是 Object.getOwnPropertyDescriptors。
ES9
一、迭代器iterators
二、promise的finally
ES10
1.flat與flatMap
(1)flat
flat() 方法會按照一個可指定的深度遞歸遍歷數組,并將所有元素與遍歷到的子數組中的元素合并為一個新數組返 回。
(2)flatMap
flatMap() 方法首先使用映射函數映射每個元素,然后將結果壓縮成一個新數組。
即:先進行map操作,再進行flat操作。
// 1.flat的使用 const nums = [10, 20, [2, 3], 90, [1, 4, [2, 4]], 90] const newNums = nums.flat() console.log(newNums); // 默認進行一次降維 [ 10, 20, 2, 3, 90, 1, 4, [ 2, 4 ], 90 ] const newNums2 = nums.flat(2) // 進行兩次降維 console.log(newNums2); // [ 10, 20, 2, 3, 90, 1, 4, 2, 4, 90 ]// 2.flatMap的使用 const nums2 = [10, 38, 40] const newNums3 = nums2.flatMap(item => {return item * 2 }) const newNums4 = nums2.map(item => {return item * 2 }) console.log(newNums3); // [ 20, 76, 80 ] console.log(newNums4); // [ 20, 76, 80 ]// 3.flatMap的應用 const messaes = ['hello world', 'hello lyh', 'my name is loc'] const words = messaes.flatMap(item => {return item.split(' ') }) console.log(words); // 輸出如下:// [// 'hello', 'world',// 'hello', 'lyh',// 'my', 'name',// 'is', 'loc'// ] const words2 = messaes.map(item => {return item.split(' ') }) console.log(words2); // 輸出如下:// [// [ 'hello', 'world' ],// [ 'hello', 'lyh' ],// [ 'my', 'name', 'is', 'loc' ]// ] // 區別:flatMap是先進行map操作,再進行flat操作2.entries轉對象
const obj = {name: 'tjx',age: 19,height: 1.88 } const entries = Object.entries(obj) console.log(entries); // [ [ 'name', 'tjx' ], [ 'age', 19 ], [ 'height', 1.88 ] ] // 傳統方法 const newObj1 = {} for (const entry of entries) {newObj1[entry[0]] = entry[1] } console.log(newObj1); // { name: 'tjx', age: 19, height: 1.88 } // 使用ES10新增方法 const newObj2 = Object.fromEntries(entries) console.log(newObj2); // { name: 'tjx', age: 19, height: 1.88 } console.log("((((((((("); // 應用 const queryString = 'name=tjx&age=19&height=1.88' const queryParams = new URLSearchParams(queryString) console.log(queryParams); // URLSearchParams { 'name' => 'tjx', 'age' => '19', 'height' => '1.88' } for (const param of queryParams) {console.log(param); // 輸出如下:// [ 'name', 'tjx' ]// [ 'age', '19' ]// [ 'height', '1.88' ] } const paramObj = Object.fromEntries(queryParams) console.log(paramObj); // { name: 'tjx', age: '19', height: '1.88' }3.trimStart與trimEnd
trimStart 去除字符串前面的空格,trimEnd去除字符串后面的空格。
4. Symbol description
5. Optional catch binding
ES11
1.BigInt
數據類型BigInt,用于表示大的整數;
const maxInt = Number.MAX_SAFE_INTEGER console.log(maxInt); // 9007199254740991const bigInt = 9007199254740991100n; // 使用n表示BigInt // console.log(bigInt + 10); // 報錯,只能同類型運算 console.log(bigInt + 10n); // 9007199254740991110nconst num = 100 console.log(bigInt + BigInt(num)); // 9007199254740991000const smallNum = Number(bigInt) console.log(smallNum); // 90071992547409910002.空值合并運算符
const fooa = '' const result1 = fooa || '默認值' const result2 = fooa ?? '默認值' console.log(result1); // 默認值 console.log(result2); // '' // 作用:有時為了那個值就是空字符串,使用 || 會出現不想要的錯誤,所以使用 ??3.可選鏈
可選鏈也是ES11中新增一個特性,主要作用是讓我們的代碼在進行null和undefined判斷時更加清晰和簡潔
const obj = {friend: {girlFriend: {name: 'luck'}} } // 傳統方式需要一個一個判斷 if (obj.friend && obj.friend.girlFriend) {console.log(obj.friend.girlFriend.name); } // 可選鏈 console.log(obj.friend?.girlFriend?.name);4.globalThis
在瀏覽器中globalThis指向window,在node中globalThis指向node的全局變量。
ES12
1.FinalizationRegistry
FinalizationRegistry 對象可以讓你在對象被垃圾回收時請求一個回調。
FinalizationRegistry 提供了這樣的一種方法:當一個在注冊表中注冊的對象被回收時,請求在某個時間點上調 用一個清理回調。(清理回調有時被稱為 finalizer ); 你可以通過調用register方法,注冊任何你想要清理回調的對象,傳入該對象和所含的值;
let objp = {name: 'tjx' } const registry = new FinalizationRegistry(value => {console.log("對象被銷毀了", value); }) registry.register(objp, 'obj')objp = null2.WeakRefs
如果我們默認將一個對象賦值給另外一個引用,那么這個引用是一個強引用: 如果我們希望是一個弱引用的話,可以使用WeakRef;
let obj = { name: 'tjx'} let inof = new WeakRef(obj)總結
- 上一篇: 2022.10.4 英语背诵
- 下一篇: RGB合成图片(misc)