ES6中常見基本知識點的基本使用實例匯總
前言
學(xué)習(xí)了coderwhy的JavaScript高級語法視頻課的筆記
如有錯誤或者不合適的地方,敬請見諒,歡迎指出和拓展,謝謝各位了
1、字面量的增強
var name = 'xxx' var age = 12 var obj = { // 1.property shorthand(屬性的簡寫) name: name, age, // 2.method shorthand(方法的簡寫) foo: function () { console.log(1) }, foo2: () => { console.log(2) }, foo3() { console.log(3) }, // 3.computed property name(計算屬性名) [name + 123]: 'yyy' } obj.foo() //1 obj.foo2() //2 obj.foo3() //3 obj[name + 456] = 'zzz' console.log(obj) // { // name: 'xxx', // age: 12, // foo: [Function: foo], // foo2: [Function: foo2], // foo3: [Function: foo3], // xxx123: 'yyy', // xxx456: 'zzz' // }
2、解構(gòu)Destructuring
- 數(shù)組解構(gòu)
var arr = ['aaa', 'bbb', 'ccc'] // 以前的做法 // var a1 = arr[0] // var a2 = arr[1] // var a3 = arr[2] // 1、對數(shù)組的解構(gòu) var [a1, a2, a3] = arr console.log(a1, a2, a3) //aaa bbb ccc // 2、解構(gòu)后面的元素 var [, , a4] = arr console.log(a4) //ccc // 3、解構(gòu)出一個元素,后面的元素放到一個新數(shù)組中 var [a5, ...newArr] = arr console.log(a5, newArr) //aaa [ 'bbb', 'ccc' ] // 4、解構(gòu)的默認(rèn)值 var [a6, a7, a8, a9 = 'ddd'] = arr console.log(a6, a7, a8, a9) //aaa bbb ccc ddd
- 對象解構(gòu)
var obj = { name: 'xxx', age: 123, address: '廣東' } //1、全部解構(gòu) var { name, age, address } = obj console.log(name, age, address) //xxx 123 廣東 //2、解構(gòu)單個 var { age } = obj console.log(age) //123 // 3、重新命名 var { age: newAge } = obj console.log(newAge) //123 //4、解構(gòu)的默認(rèn)值 var { color: newColor = 'red' } = obj console.log(newColor) //red //5、函數(shù)中 function foo(o) { console.log(o.name, o.age) //xxx 123 } foo(obj) function foo2({ name, age }) { console.log(name, age) //xxx 123 } foo2(obj) function foo3({ name, age=456}) { console.log(name, age) //xxx 123 } foo3(obj)
3、let和const
- 基本語法
// 1、從直觀的角度來說,let和var是沒有太大的區(qū)別的,都是用于聲明一個變量 let bar = "bar" // 2、const constant(常量/衡量) const name = "abc" // 3、 // 注意事項一: const本質(zhì)上是傳遞的值不可以修改 // 但是如果傳遞的是一個引用類型(內(nèi)存地址), 可以通過引用找到對應(yīng)的對象, 去修改對象內(nèi)部的屬性, 這個是可以的 const obj = { foo: "foo" } obj2.foo = "aaa" console.log(obj.foo)// aaa // 4、 // 注意事項二: 通過let/const定義的變量名是不可以重復(fù)定義 // let foo = "abc" // let foo = "cba"
- 作用域提升
在執(zhí)行上下文的詞法環(huán)境創(chuàng)建出來的時候,變量事實上已經(jīng)被創(chuàng)建了,只是這個變量是不能被提前訪問的。
那么我們自己從字面量上理解:在聲明變量的作用域中,如果這個變量可以在聲明之前被訪問,那么我們可以稱之為作用域提升。
// 作用域提升: 能提前被訪問 console.log(foo)// undefined var foo = "foo" // let/const他們是沒有作用域提升 // foo被創(chuàng)建出來了, 但是不能被訪問 // Reference(引用)Error: Cannot access 'foo' before initialization(初始化) console.log(foo) let foo = "foo"
- let、const和window的關(guān)系
- 我們知道,在全局通過var來聲明一個變量,事實上會在window上添加一個屬性,但是let、const是不會給window上添加任何屬性。
- 基于早期ECMA的版本規(guī)范:
- 每一個執(zhí)行上下文會被關(guān)聯(lián)到一個變量對象(variable object,VO),在源代碼中的變量和函數(shù)聲明會被作為屬性添加到VO中。對與函數(shù)來說,參數(shù)也會被添加到VO中。
- 在最新的ECMA的版本規(guī)范中,對于一些詞匯進(jìn)行了修改:
- 每一個執(zhí)行上下文會被關(guān)聯(lián)到一個變量環(huán)境(VariableEnvironment,VE),在執(zhí)行代碼中的變量和函數(shù)聲明會被作為環(huán)境記錄(Environment Record)添加到變量環(huán)境中。對與函數(shù)來說,參數(shù)也會被環(huán)境記錄添加到變量環(huán)境中。
也就是說我們聲明的變量和環(huán)境記錄是被添加到變量環(huán)境中的,但是標(biāo)準(zhǔn)沒有規(guī)定這個對象是window對象或者其他對象,那么JS引擎在解析的時候,其實會有自己的實現(xiàn)。比如v8中其實是通過VariableMap的一個hashmap來實現(xiàn)它們的存儲的(VE->variables_)。
那么window對象呢?而window對象是早期的GO對象,在最新的實現(xiàn)中其實是瀏覽器添加的全局對象,并且 一直保持了window和var之間值的相等性。
var a = 123 let b = 456 console.log(window.a) //123 console.log(window.b) //undefined
4、作用域
- ES5作用域(ES5中沒有塊級作用域)
// 在ES5中只有兩個東西會形成作用域 // 1.全局作用域 // 2.函數(shù)(局部)作用域 function foo() { var bar = "bar" }
- ES6作用域(新增一個塊級作用域)
// ES6的代碼塊級作用域 // 對let/const/function/class聲明的類型是有效 { let foo = 'why' function demo() { console.log('demo function') } class Person {} } console.log(foo) // foo is not defined // 不同的瀏覽器有不同實現(xiàn)的(大部分瀏覽器為了兼容以前的代碼, 讓function是沒有塊級作用域) demo() //demo function var p = new Person() // Person is not defined
// 1、if語句的代碼就是塊級作用域 if (true) { var foo = 'foo' let bar = 'bar' } console.log(foo) //foo console.log(bar) //bar is not defined // 2、switch語句的代碼也是塊級作用域 var color = 'red' switch (color) { case 'red': var foo2 = 'foo' let bar2 = 'bar' } console.log(foo2) //foo console.log(bar2) //bar2 is not defined // 3、for語句的代碼也是塊級作用域 for (var i = 0; i < 10; i++) { console.log('Hello World' + i) // Hello World0 // Hello World1 // Hello World2 // Hello World3 // Hello World4 // Hello World5 // Hello World6 // Hello World7 // Hello World8 // Hello World9 } console.log(i) //10 for (let j = 0; j < 10; j++) {} console.log(j) //j is not defined
- 塊級作用域的應(yīng)用場景
點擊不同的button打印出不同的button編號的兩種實現(xiàn)方法。
const btns = document.getElementsByTagName('button') // 1、var沒有塊級作用域 for (var i = 0; i < btns.length; i++) { ;(function (n) { btns[i].onclick = function () { console.log('第' + n + '個按鈕被點擊') } })(i) } // 2、let有塊級作用域 for (let i = 0; i < btns.length; i++) { btns[i].onclick = function () { console.log('第' + i + '個按鈕被點擊') } }
- 塊級作用域的補充
const names = ['abc', 'cba', 'nba'] // 1、不可以使用const,因為i的每次循環(huán)(生成一個塊級作用域)都不一樣,其實都是需要上一次的i進(jìn)行i++賦值給下一個i for (let i = 0; i < names.length; i++) { console.log(names[i]) } // 2、for...of: ES6新增的遍歷數(shù)組(對象) // 因為每次遍歷(生成一個塊級作用域)的值都賦給一個item,所以不需要上一次item的值進(jìn)行操作 for (const item of names) { console.log(item) }
- let和const的暫時性死區(qū)
在ES6中,我們還有一個概念稱之為暫時性死區(qū):它表達(dá)的意思是在一個代碼中,使用let、const聲明的變量,在聲明之前,變量都是不可以訪問的,我們將這種現(xiàn)象稱之為 temporal dead zone(暫時性死區(qū),TDZ)。
var foo = 'foo' // 塊級作用域 if (true) { console.log(foo) //Cannot access 'foo' before initialization let foo = 'abc' }
- var、let、const的選擇
- 對于var的使用:
- 我們需要明白一個事實,var所表現(xiàn)出來的特殊性:比如作用域提升、window全局對象、沒有塊級作用域等都是一些 歷史遺留問題;
- 其實是JavaScript在設(shè)計之初的一種語言缺陷;
- 對于let、const:
- 對于let和const來說,是目前開發(fā)中推薦使用的;
- 我們會優(yōu)先推薦使用const,這樣可以保證數(shù)據(jù)的安全性不會被隨意的篡改;
- 只有當(dāng)我們明確知道一個變量后續(xù)會需要被重新賦值時,這個時候再使用let;
- 這種在很多其他語言里面也都是一種約定俗成的規(guī)范,盡量我們也遵守這種規(guī)范;
5、模板子符串
- 基本使用
// ES6之前拼接字符串和其他標(biāo)識符 const name = 'why' const age = 18 const height = 1.88 console.log('my name is ' + name + ', age is ' + age + ', height is ' + height) // ES6提供模板字符串 `` // 1、 const message = `my name is ${name}, age is ${age}, height is ${height}` console.log(message) // 2、 const info = `age double is ${age * 2}` console.log(info) // 3、 function doubleAge() { return age * 2 } const info2 = `double age is ${doubleAge()}` console.log(info2)
- 標(biāo)簽?zāi)0遄址?/li>
// 第一個參數(shù)依然是模塊字符串中整個字符串, 只是被切成多塊,放到了一個數(shù)組中 // 第二個參數(shù)是模塊字符串中, 第一個 ${} function foo(m, n, x) { console.log(m, n, x) } // 另外調(diào)用函數(shù)的方式: 標(biāo)簽?zāi)K字符串 foo`` //[ '' ] undefined undefined foo`Hello World` //[ 'Hello World' ] undefined undefined const name = 'why' const age = 18 foo`Hello${name}Wo${age}rld` //[ 'Hello', 'Wo', 'rld' ] why 18
6、函數(shù)
- 函數(shù)的默認(rèn)參數(shù)
// 1.ES6可以給函數(shù)參數(shù)提供默認(rèn)值 function foo(m = 'aaa', n = 'bbb') { console.log(m, n) } foo(0)// 0 bbb // 2.對象參數(shù)和默認(rèn)值以及解構(gòu) function printInfo({ name, age } = { name: 'why', age: 18 }) { console.log(name, age) } printInfo({ name: 'kobe', age: 40 }) //kobe 40 // 另外一種寫法 function printInfo1({ name = 'why', age = 18 } = {}) { console.log(name, age) } printInfo1() //why 18 // 3.有默認(rèn)值的形參最好放到最后 function bar(x, y, z = 30) { console.log(x, y, z) } bar(10, 20) //10 20 30 // 4.有默認(rèn)值的函數(shù)的length屬性 function baz(x, y, z, m, n = 30) { console.log(x, y, z, m, n) } console.log(baz.length)// 4
- 函數(shù)的剩余次數(shù)
function foo(m, n, ...args) { console.log(m, n) //20 30 console.log(args) //[ 40, 50, 60 ] console.log(arguments) //[Arguments] { '0': 20, '1': 30, '2': 40, '3': 50, '4': 60 } } foo(20, 30, 40, 50, 60) //function foo (...args,m, n) // rest paramaters必須放到最后 // Rest parameter must be last formal parameter
- 箭頭函數(shù)
箭頭函數(shù)是沒有顯式原型的,所以不能作為構(gòu)造函數(shù),使用new來創(chuàng)建對象。
function foo() {} console.log(foo.prototype) //{} const f = new foo() console.log(f.__proto__) //{} var bar = () => { console.log(this, arguments) //箭頭函數(shù)本身沒有 } console.log(bar.prototype) //undefined const f2 = new bar() //bar is not a constructor
7、展開語法
const names = ['abc', 'cba', 'nba'] const name = 'why' const info = { name: 'why', age: 18 } // 1.函數(shù)調(diào)用時 function foo(x, y, z) { console.log(x, y, z) } // foo.apply(null, names) foo(...names) //abc cba nba foo(...name) //w h y // 2.構(gòu)造數(shù)組時 const newNames = [...names, ...name] console.log(newNames) //[ 'abc', 'cba', 'nba', 'w', 'h', 'y' ] // 3.構(gòu)建對象字面量時ES2018(ES9) const obj = { ...info, address: '廣州市', ...names } console.log(obj) // { // '0': 'abc', // '1': 'cba', // '2': 'nba', // name: 'why', // age: 18, // address: '廣州市' // }
- 展開語法是淺拷貝
const info = { name: 'why', friend: { name: 'kobe' } } const obj = { ...info, name: 'coderwhy' } // console.log(obj) obj.friend.name = 'james' console.log(info.friend.name) //james
8、數(shù)值表示
const num1 = 100 // 十進(jìn)制 // b -> binary const num2 = 0b100 // 二進(jìn)制 // o -> octonary const num3 = 0o100 // 八進(jìn)制 // x -> hexadecimal const num4 = 0x100 // 十六進(jìn)制 console.log(num1, num2, num3, num4) //100 4 64 256 // 大的數(shù)值的連接符(ES2021 ES12),該寫法方便閱讀 const num = 10_000_000_000_000_000 console.log(num) //10000000000000000
9、Symbol的基本使用
- 在ES6之前,對象的屬性名都是字符串形式,那么很容易造成屬性名的沖突,比如原來有一個對象,我們希望在其中添加一個新的屬性和值,但是我們在不確定它原來內(nèi)部有什么內(nèi)容的情況下, 很容易造成沖突,從而覆蓋掉它內(nèi)部的某個屬性;
- Symbol是ES6中新增的一個基本數(shù)據(jù)類型,翻譯為符號,用來生成一個獨一無二的值,Symbol即使多次創(chuàng)建值,它們也是不同的。Symbol值是通過Symbol函數(shù)來生成的,生成后可以作為屬性名也就是在ES6中,對象的屬性名可以使用字符串,也可以使用Symbol值;
- 我們也可以在創(chuàng)建Symbol值的時候傳入一個描述description,這個是ES2019(ES10)新增的特性。
// 1.ES6之前, 對象的屬性名(key) var obj = { name: 'why', friend: { name: 'kobe' }, age: 18 } obj['newName'] = 'james' console.log(obj) //{ name: 'why', friend: { name: 'kobe' }, age: 18, newName: 'james' } // 2.ES6中Symbol的基本使用 const s1 = Symbol() const s2 = Symbol() console.log(s1 === s2) //false // ES2019(ES10)中, Symbol還有一個描述(description) const s3 = Symbol('aaa') console.log(s3.description) //aaa // 3.Symbol值作為key // 3.1.在定義對象字面量時使用 const obj2 = { [s1]: 'abc', [s2]: 'cba' } // 3.2.新增屬性 obj2[s3] = 'nba' // 3.3.Object.defineProperty方式 const s4 = Symbol() Object.defineProperty(obj2, s4, { enumerable: true, configurable: true, writable: true, value: 'mba' }) console.log(obj2[s1], obj2[s2], obj2[s3], obj2[s4]) //abc cba nba mba // 注意: 不能通過.語法獲取 console.log(obj2.s1) //undefined // 4.使用Symbol作為key的屬性名,在遍歷/Object.keys等中是獲取不到這些Symbol值 // 需要Object.getOwnPropertySymbols來獲取所有Symbol的key console.log(Object.keys(obj2)) //[] console.log(Object.getOwnPropertyNames(obj2)) //[] console.log(Object.getOwnPropertySymbols(obj2)) //[ Symbol(), Symbol(), Symbol(aaa), Symbol() ] const sKeys = Object.getOwnPropertySymbols(obj2) for (const sKey of sKeys) { console.log(obj2[sKey]) // abc // cba // nba // mba } // 5.Symbol.for(key)/Symbol.keyFor(symbol) const sa = Symbol.for('aaa') const sb = Symbol.for('aaa') console.log(sa === sb) //true const key = Symbol.keyFor(sa) console.log(key) //aaa const sc = Symbol.for(key) console.log(sa === sc) //true
10、Set
在ES6之前,我們存儲數(shù)據(jù)的結(jié)構(gòu)主要有兩種:數(shù)組、對象,在ES6中新增了另外兩種數(shù)據(jù)結(jié)構(gòu):Set、Map,以及它們的另外形式WeakSet、WeakMap。Set是一個新增的數(shù)據(jù)結(jié)構(gòu),可以用來保存數(shù)據(jù),類似于數(shù)組,但是和數(shù)組的區(qū)別是元素不能重復(fù)(那么Set有一個非常常用的功能就是給數(shù)組去重)。創(chuàng)建Set我們需要通過Set構(gòu)造函數(shù)(暫時沒有字面量創(chuàng)建的方式)。
- Set常見的屬性:
- size:返回Set中元素的個數(shù);
- Set常用的方法:
- add(value):添加某個元素,返回Set對象本身;
- delete(value):從set中刪除和這個值相等的元素,返回boolean類型;
- has(value):判斷set中是否存在某個元素,返回boolean類型;
- clear():清空set中所有的元素,沒有返回值;
- forEach(callback, [, thisArg]):通過forEach遍歷set;
- 另外Set是支持for...of的遍歷的。
- 基本使用
// 1.創(chuàng)建Set結(jié)構(gòu) var set = new Set() set.add(2) set.add(2) set.add(30) set.add(40) set.add(2) set.add(230) console.log(set) //Set(4) { 2, 30, 40, 230 } // 2.添加對象時特別注意: // 這是兩個不同的變量 set.add({}) set.add({}) console.log(set) //Set(6) { 2, 30, 40, 230, {}, {} } // obj存儲的是地址,set存儲的元素不重復(fù) const obj = {} set.add(obj) set.add(obj) console.log(set) //Set(7) { 2, 30, 40, 230, {}, {}, {} } // 3.對數(shù)組去重(去除重復(fù)的元素) const arr = [43, 10, 26, 30, 43, 26, 10] // 3.1第一種方法 // const newArr = [] // for (const item of arr) { // if (newArr.indexOf(item) !== -1) { // newArr.push(item) // } // } // 3.2第二種方法 const arrSet = new Set(arr) // const newArr = Array.from(arrSet) const newArr = [...arrSet] console.log(newArr) //[ 43, 10, 26, 30 ] // 4.size屬性 console.log(arrSet.size) //4 // 5.Set的方法 // add arrSet.add(1000) console.log(arrSet) //Set(5) { 43, 10, 26, 30, 1000 } // delete arrSet.delete(43) console.log(arrSet) //Set(4) { 10, 26, 30, 1000 } // has console.log(arrSet.has(100)) //false // clear // arrSet.clear() console.log(arrSet) //Set(0) {} // 6.對Set進(jìn)行遍歷 arrSet.forEach(item => { console.log(item) // 10 // 26 // 30 // 1000 }) for (const item of arrSet) { console.log(item) // 10 // 26 // 30 // 1000 }
11、WeakSet
和Set類似的另外一個數(shù)據(jù)結(jié)構(gòu)稱之為WeakSet,也是內(nèi)部元素不能重復(fù)的數(shù)據(jù)結(jié)構(gòu)。
- 那么和Set有什么區(qū)別呢?
- 區(qū)別一:WeakSet中只能存放對象類型,不能存放基本數(shù)據(jù)類型;
- 區(qū)別二:WeakSet對元素的引用是弱引用,如果沒有其他引用對某個對象進(jìn)行引用,那么GC可以對該對象進(jìn)行回收;
- WeakSet常見的方法:
- add(value):添加某個元素,返回WeakSet對象本身;
- delete(value):從WeakSet中刪除和這個值相等的元素,返回boolean類型;
- has(value):判斷WeakSet中是否存在某個元素,返回boolean類型。
const weakSet = new WeakSet() // 1.區(qū)別一: 只能存放對象類型 // TypeError: Invalid value used in weak set // weakSet.add(10) // 2.區(qū)別二: 對對象是一個弱引用 let obj = { name: 'why' } const set = new Set() // 建立的是強引用 set.add(obj) // 建立的是弱引用 weakSet.add(obj) console.log(weakSet)// WeakSet { <items unknown> } // 3.WeakSet的應(yīng)用場景 const personSet = new WeakSet() class Person { constructor() { personSet.add(this) } running() { if (!personSet.has(this)) { throw new Error('不能通過非構(gòu)造方法創(chuàng)建出來的對象調(diào)用running方法') } console.log('running~', this) //running~ Person {} } } let p = new Person() p.running() // 拋出異常 // p.running.call({ name: 'why' })
如果obj=null,雖然0xa00對象還有引用。但是由于是弱引用,GC還是會回收0xa00對象。
12、Map
- 新增的數(shù)據(jù)結(jié)構(gòu)是Map,用于存儲映射關(guān)系,在之前我們可以使用對象來存儲映射關(guān)系,他們有什么區(qū)別呢?
- 事實上我們對象存儲映射關(guān)系只能用 字符串(ES6新增了Symbol) 作為屬性名(key);
- 某些情況下我們可能希望通過其他類型作為key,比如對象,這個時候會自動將對象轉(zhuǎn)成字符串來作為key;
- Map常見的屬性:
- size:返回Map中元素的個數(shù);
- Map常見的方法:
- set(key, value):在Map中添加key、value,并且返回整個Map對象;
- get(key):根據(jù)key獲取Map中的value;
- has(key):判斷是否包括某一個key,返回Boolean類型;
- delete(key):根據(jù)key刪除一個鍵值對,返回Boolean類型;
- clear():清空所有的元素;
- forEach(callback, [, thisArg]):通過forEach遍歷Map;
- Map也可以通過for of進(jìn)行遍歷。
// 1.JavaScript中對象中是不能使用對象來作為key的 const obj1 = { name: 'why' } const obj2 = { name: 'kobe' } const info = { [obj1]: 'aaa', [obj2]: 'bbb' } console.log(info) //{ '[object Object]': 'bbb' } // 2.Map就是允許我們對象類型來作為key的 // 構(gòu)造方法的使用 const map = new Map() map.set(obj1, 'aaa') map.set(obj2, 'bbb') map.set(1, 'ccc') console.log(map) // Map(3) { // { name: 'why' } => 'aaa', // { name: 'kobe' } => 'bbb', // 1 => 'ccc' // } const map2 = new Map([ [obj1, 'aaa'], [obj2, 'bbb'], [2, 'ddd'] ]) console.log(map2) // Map(3) { // { name: 'why' } => 'aaa', // { name: 'kobe' } => 'bbb', // 2 => 'ccc' // } // 3.常見的屬性和方法 console.log(map2.size) //3 // set map2.set('why', 'eee') console.log(map2) // Map(4) { // { name: 'why' } => 'aaa', // { name: 'kobe' } => 'bbb', // 2 => 'ddd', // 'why' => 'eee' // } // get(key) console.log(map2.get('why')) //eee // has(key) console.log(map2.has('why')) //true // delete(key) map2.delete('why') console.log(map2) // Map(3) { // { name: 'why' } => 'aaa', // { name: 'kobe' } => 'bbb', // 2 => 'ddd' // } // clear(),全部清空 // map2.clear() // console.log(map2) // 4.遍歷map map2.forEach((item, key) => { console.log(item, key) // aaa { name: 'why' } // bbb { name: 'kobe' } // ddd 2 }) for (const item of map2) { console.log(item[0], item[1]) // { name: 'why' } aaa // { name: 'kobe' } bbb // 2 ddd } for (const [key, value] of map2) { console.log(key, value) // { name: 'why' } aaa // { name: 'kobe' } bbb // 2 ddd }
13、WeakMap
和Map類型的另外一個數(shù)據(jù)結(jié)構(gòu)稱之為WeakMap,也是以鍵值對的形式存在的。
- 那么和Map有什么區(qū)別呢?
- 區(qū)別一:WeakMap的key只能使用對象,不接受其他的類型作為key;
- 區(qū)別二:WeakMap的key對對象想的引用是弱引用,如果沒有其他引用引用這個對象,那么GC可以回收該對象;
- WeakMap常見的方法有四個:
- set(key, value):在Map中添加key、value,并且返回整個Map對象;
- get(key):根據(jù)key獲取Map中的value;
- has(key):判斷是否包括某一個key,返回Boolean類型;
- delete(key):根據(jù)key刪除一個鍵值對,返回Boolean類型;
const obj = {name: "obj1"} // 1.WeakMap和Map的區(qū)別二:弱引用 const map = new Map() map.set(obj, "aaa") const weakMap = new WeakMap() weakMap.set(obj, "aaa") // 2.區(qū)別一: 不能使用基本數(shù)據(jù)類型 // weakMap.set(1, "ccc") // 3.常見方法 // get方法 console.log(weakMap.get(obj))//aaa // has方法 console.log(weakMap.has(obj))//true // delete方法 console.log(weakMap.delete(obj))//true // WeakMap { <items unknown> } console.log(weakMap)//WeakMap { <items unknown> }
- 使用場景:響應(yīng)式原理中的WeakMap的使用(簡單實現(xiàn))
// 應(yīng)用場景(vue3響應(yīng)式原理) const obj1 = { name: 'why', age: 18 } function obj1NameFn1() { console.log('obj1NameFn1被執(zhí)行') } function obj1NameFn2() { console.log('obj1NameFn2被執(zhí)行') } function obj1AgeFn1() { console.log('obj1AgeFn1') } function obj1AgeFn2() { console.log('obj1AgeFn2') } const obj2 = { name: 'kobe', height: 1.88, address: '廣州市' } function obj2NameFn1() { console.log('obj1NameFn1被執(zhí)行') } function obj2NameFn2() { console.log('obj1NameFn2被執(zhí)行') } // 1.創(chuàng)建WeakMap const weakMap = new WeakMap() // 2.收集依賴結(jié)構(gòu) // 2.1.對obj1收集的數(shù)據(jù)結(jié)構(gòu) const obj1Map = new Map() obj1Map.set('name', [obj1NameFn1, obj1NameFn2]) obj1Map.set('age', [obj1AgeFn1, obj1AgeFn2]) weakMap.set(obj1, obj1Map) // 2.2.對obj2收集的數(shù)據(jù)結(jié)構(gòu) const obj2Map = new Map() obj2Map.set('name', [obj2NameFn1, obj2NameFn2]) weakMap.set(obj2, obj2Map) // 3.如果obj1.name發(fā)生了改變 // Proxy/Object.defineProperty obj1.name = 'james' const targetMap = weakMap.get(obj1) const fns = targetMap.get('name') fns.forEach(item => item()) // obj1NameFn1被執(zhí)行 // obj1NameFn2被執(zhí)行
總結(jié)
到此這篇關(guān)于ES6中常見基本知識點的基本使用實的文章就介紹到這了,更多相關(guān)ES6常見知識點內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- ES6知識點整理之對象解構(gòu)賦值應(yīng)用示例
- ES6知識點整理之函數(shù)對象參數(shù)默認(rèn)值及其解構(gòu)應(yīng)用示例
- ES6知識點整理之?dāng)?shù)組解構(gòu)和字符串解構(gòu)的應(yīng)用示例
- ES6學(xué)習(xí)筆記之字符串、數(shù)組、對象、函數(shù)新增知識點實例分析
- ES6知識點整理之Proxy的應(yīng)用實例詳解
- ES6知識點整理之函數(shù)數(shù)組參數(shù)的默認(rèn)值及其解構(gòu)應(yīng)用示例
- ES6知識點整理之模塊化的應(yīng)用詳解
- ES6知識點整理之String字符串新增常用方法示例
- 關(guān)于ES6新特性最常用的知識點匯總
相關(guān)文章
JavaScript中0、空字符串、''0''是true還是false的知識點分享
在本篇文章里小編給大家整理的是JavaScript中0、空字符串、'0'是true還是false的知識點分享,有需要的朋友們參考下。2019-09-09javascript設(shè)計模式 – 模板方法模式原理與用法實例分析
這篇文章主要介紹了javascript設(shè)計模式 – 模板方法模式原理,結(jié)合實例形式分析了javascript模板方法模式相關(guān)概念、原理、用法及操作注意事項,需要的朋友可以參考下2020-04-04微信小程序?qū)崿F(xiàn)紅包功能(后端PHP實現(xiàn)邏輯)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)紅包功能,以及后端PHP實現(xiàn)邏輯,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07