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 }