ES5中Object的屬性必須是key-value形式數組
var x = 0, y = 0; obj = { x: x, y: y };
ES6中當key與value相同時能夠簡寫這種形式數據結構
var x = 0, y = 0 obj = { x, y }
在 ES6 以前 Object 的 key 在定義時必須是字符串,若是想增長「動態」的 key,必須是先計算出 key,利用 object[key] = value 的方式來修改;異步
在 ES6 以後能夠直接用變量或者表達式來定義 key函數
let obj = { foo: 'bar', ['baz'+ quux()]: 42 }
ES5中Object的屬性只支持常規函數,對異步函數式不支持的性能
var obj = { foo: function (a, b) { }, bar: function (x, y) { } // quux: no equivalent in ES5 }
ES6中對象內的方法能夠簡寫,包括常規函數和異步函數ui
let obj = { foo (a, b) { }, bar (x, y) { }, * quux (x, y) { } }
生成Set實例this
let s = new Set() let s = new Set([1, 2, 3, 4]) //初始化的參數必須是可遍歷的,能夠是數組或者自定義遍歷的數據結構
添加數據prototype
s.add('hello') s.add('goodbye') s.add('hello').add('goodbye') //Set 數據結構不容許數據重複,因此添加劇復的數據是無效的
刪除數據code
刪除數據分兩種,一種是刪除指定的數據,一種是刪除所有數據對象
// 刪除指定數據 s.delete('hello') // true // 刪除所有數據 s.clear()
統計數據
Set 能夠快速進行統計數據,如數據是否存在、數據的總數
// 判斷是否包含數據項,返回 true 或 false s.has('hello') // true // 計算數據項總數 s.size // 2
查詢數據
console.log(s.keys()); // SetIterator {"hello", "goodbye"} console.log(s.values()); // SetIterator {"hello", "goodbye"} console.log(s.entries()); // SetIterator {"hello" => "hello", "goodbye" => "goodbye"} s.forEach(item => { console.log(item) // hello // goodbye }) for (let item of s) { console.log(item) } // hello// goodbye
生成實例
let map = new Map([iterable]) //Iterable 能夠是一個數組或者其餘 iterable 對象,其元素爲鍵值對(兩個元素的數組,例如: [[ 1, ‘one’ ],[ 2, ‘two’ ]])。 每一個鍵值對都會添加到新的 Map。null 會被當作 undefined
添加數據
let keyObj = {} let keyFunc = function () {} let keyString = 'a string' // 添加鍵 map.set(keyString, "和鍵'a string'關聯的值") map.set(keyObj, '和鍵keyObj關聯的值') map.set(keyFunc, '和鍵keyFunc關聯的值')
刪除數據
// 刪除指定的數據 map.delete(keyObj) // 刪除全部數據 map.clear()
統計數據
// 統計全部 key-value 的總數 console.log(map.size) //2 // 判斷是否有 key-value console.log(map.has(keyObj)) // true
查詢數據
console.log(map.get(keyObj)) // 和鍵keyObj關聯的值 console.log(map.keys()) // Iterator console.log(map.values()) // Iterator console.log(map.entries()) // Iterator map.forEach((value, key, map) => { console.log(value, key, map) }, thisArg) for ([key, value] of map) { console.log(key, value) }
鍵的類型
一個Object的鍵只能是字符串或者 Symbols,但一個 Map 的鍵能夠是任意值,包括函數、對象、基本類型。
鍵的順序
Map 中的鍵值是有序的,而添加到對象中的鍵則不是。所以,當對它進行遍歷時,Map 對象是按插入的順序返回鍵值。
鍵值對的統計
你能夠經過 size 屬性直接獲取一個 Map 的鍵值對個數,而 Object 的鍵值對個數只能手動計算。
鍵值對的遍歷
Map 可直接進行迭代,而 Object 的迭代須要先獲取它的鍵數組,而後再進行迭代。
性能
Map 在涉及頻繁增刪鍵值對的場景下會有些性能優點
Set 是無重複值的有序列表。根據 Object.is()
方法來判斷其中的值不相等,以保證無重複。 Set 會自動移除重複的值,所以你可使用它來過濾數組中的重複值並返回結果。 Set並非數組的子類型,因此你沒法隨機訪問其中的值。但你可使用has()
方法來判斷某個值是否存在於 Set 中,或經過 size
屬性來查看其中有多少個值。 Set 類型還擁有forEach()
方法,用於處理每一個值。
Map 是有序的鍵值對,其中的鍵容許是任何類型。與 Set 類似,經過調用 Object.is()
方法來判斷重複的鍵,這意味着能將數值 5 與字符串 "5" 做爲兩個相對獨立的鍵。使用set()
方法能將任何類型的值關聯到某個鍵上,而且該值此後能用 get()
方法提取出來。Map 也擁有一個 size
屬性與一個 forEach()
方法,讓項目訪問更容易。
object.assign方法實行的是淺拷貝,而不是深拷貝
若是目標對象中的屬性具備相同的鍵,則屬性將被源對象中的屬性覆蓋。後面的源對象的屬性將相似地覆蓋前面的源對象的屬性
若是源對象的屬性值是一個對象的引用,會直接指向該引用。以下例子中,由於source的一個鍵a指向的是一個對象。因此在拷貝過程當中只是將target的鍵a也指向該對象。因此每次更改a鍵下的內容,都會致使全局全部的相關輸出隨之改變,由於他們都指向同一個對象
const target = {a:{b:1,c:2},e:2} const source = {a:{b:3},e:2,f:2} Object.assign(target,source) console.log(target) console.log(source) //截至此時控制面板輸出爲 //{a: {b:3}, e: 2, f: 2} //{a: {b:3}, e: 2, f: 2} target.e = 10 source.e = 20 console.log(target) console.log(source) //截至此時控制面板輸出爲 //{a: {b:3}, e: 2, f: 2} //{a: {b:3}, e: 2, f: 2} //{a: {b:3}, e: 10, f: 2} //{a: {b:3}, e: 20, f: 2} target.a.b = 100 console.log(target) console.log(source) //截至此時控制面板輸出爲 //{a: {b:100}, e: 2, f: 2} //{a: {b:100}, e: 2, f: 2} //{a: {b:100}, e: 10, f: 2} //{a: {b:100}, e: 20, f: 2} //{a: {b:100}, e: 20, f: 2} //{a: {b:100}, e: 20, f: 2} source.a.b = 1000 console.log(target)//{a: {b:1000}, e: 10, f: 2} console.log(source)//{a: {b:1000}, e: 20, f: 2} //截至此時控制面板輸出爲 //{a: {b:1000}, e: 2, f: 2} //{a: {b:1000}, e: 2, f: 2} //{a: {b:1000}, e: 10, f: 2} //{a: {b:1000}, e: 20, f: 2} //{a: {b:1000}, e: 10, f: 2} //{a: {b:1000}, e: 20, f: 2} target.a.h = 200 console.log(target)//{a: {b:1000,h:200}, e: 20, f: 2} console.log(source)//{a: {b:1000}, e: 20, f: 2} //截至此時控制面板輸出爲 //{a: {b: 1000, h: 200}, e: 2, f: 2} //{a: {b: 1000, h: 200}, e: 2, f: 2} //{a: {b: 1000, h: 200}, e: 10, f: 2} //{a: {b: 1000, h: 200}, e: 20, f: 2} //{a: {b: 1000, h: 200}, e: 10, f: 2} //{a: {b: 1000, h: 200}, e: 20, f: 2} //{a: {b: 1000, h: 200}, e: 20, f: 2} //{a: {b: 1000, h: 200}, e: 20, f: 2}
class Point { constructor(x, y) { Object.assign(this, {x, y}); } } Object.assign(SomeClass.prototype, { someMethod(arg1, arg2) { ··· }, anotherMethod() { ··· } }); // 等同於下面的寫法 SomeClass.prototype.someMethod = function (arg1, arg2) { ··· }; SomeClass.prototype.anotherMethod = function () { ··· };
const obj = { a: 1 }; const copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
const o1 = { a: 1 }; const o2 = { b: 2 }; const o3 = { c: 3 }; const obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目標對象自身也會改變。 console.log(o2); // {b: 2} console.log(o3); // {c: 3} const merge = (target, ...sources) => Object.assign(target, ...sources); const merge = (...sources) => Object.assign({}, ...sources); //和空對象合併後返回一個全新對象
const o1 = { a: 1, b: 1, c: 1 }; const o2 = { b: 2, c: 2 }; const o3 = { c: 3 }; const obj = Object.assign({}, o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 }