1.Object
在ES6之前Object的属性必须是key-value形式,如下:
var x = 0, y = 0;
obj = { x: x, y: y }
在ES6之后是可以用简单的形式来表达:
var x = 0, y = 0;
obj = { x, y }
在ES6之前Object的key在定义时必须是字符串,如果想增加“动态”的key,必须是先计算的key,利用object[key] = value的方式来修改。
在ES6之后可以直接用变量或者表达式来定义key。
let obj = {
foo: 'bar',
["baz" + "ba"] : 2
}
而不用这样写:
let obj = {
foo: 'bar',
}
obj["baz" + "ba"] = 2
从ES6开始对象内的方法可以简写,包括常规函数和异步函数。
let obj = {
foo(a, b) {
console.log(a, b)
},
bar(x, y) {
console.log(x, y)
},
*quux(x, y) {
console.log(x, y)
}
}
在ES5时代只能这样写
let obj = {
foo: function (a, b) {
console.log(a, b)
},
bar: function (x, y) {
console.log(x, y)
},
}
2.Set
在JavaScript里通常使用Array或Object来存储数据。但是在频繁操作数据的过程中查找或者统计需要手动实现,不能简单直接的使用。
比如如何保证Array是去重的,如何统计Object的数据总数,必须自己手动实现类似的需求,不方便。
在ES6中为了解决上述问题,新增了数据结构Set和Map,它们分别对应传统数据结构的“集合”和“字典”。
- 生成Set实例
let s = new Set()
可以定义一个空的Set实例,也可以在实例化的同时传入默认的数据。
let s = new Set([1, 2, 3, 4])
注意:初始化 的参数必须是可遍历的,可以是数组或者自定义遍历的数据结构。
- 添加数据
s.add('hello')
s.add('world')
或者
s.add('hello').add('world')
注意:Set数据结构不允许数据重复,所以添加重复的数据是无效的。
- 删除数据
删除数据分为两种:删除指定的数据;删除全部数据。
//删除指定数据
s.delete('hello')
// 删除全部数据
s.clear()
- 统计数据
Set可以快速进行统计数据,如数据是否存在、数据的总数。
// 判断是否包含数据项,返回true或false
s.has('hello')
// 计算数据项总数
s.size
- 查询数据
keys(): 返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
for…of:可以直接遍历每个成员
let s = new Set()
s.add('hello')
s.add('world')
console.log(s.keys()) //{"hello", "world"}
console.log(s.values()) //{"hello", "world"}
console.log(s.entries()) //{"hello" => "hello", "world" => "world"}
s.forEach(item => {
console.log(item) //hello world
})
for(let item of s){
console.log(item) //hello world
}
3.Map
Map是用来实现字典的功能(Object键值对)。
- 实例化
let map = new Map([iterable])
iterable可以是一个数组或者其他iterable对象,其元素为键值对(两个元素的数组,例如:[[1,‘one’],[2,‘two’]])。每个键值对都会添加到新的Map。null会被当做undefined。
- 添加数据
let map = new Map()
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)
// 判断是否有key-value
console.log(map.has(keyObj)) //true
- 查询数据
get()方法返回某个Map对象中的一个指定元素;
keys()返回一个新的iterator对象。它包含按照顺序插入Map对象中的每个元素的key值;
values()方法返回一个新的iterator对象。它包含按顺序插入Map对象中每个元素的value值;
entries()方法返回一个新的包含[key,value]对的iterator对象,返回的迭代器的迭代顺序与Map对象的插入顺序相同;
forEach()方法将会插入顺序duiMap对象中的每一个键值对执行一次参数中提供的回调函数;
for…of可以直接遍历每个成员;
let map = new Map()
let keyObj = {}
let keyFunc = function () { }
let keyString = 'a string'
map.set(keyString, "和键'a string'关联的值")
map.set(keyObj, "和键keyObj关联的值")
map.set(keyFunc, "和键keyFunc关联的值")
console.log(map.get(keyObj)) //和键keyObj关联的值
console.log(map.keys()) // 0: "a string"
// 1: Object
// 2: function () { }
console.log(map.values()) // 0: "和键'a string'关联的值"
// 1: "和键keyObj关联的值"
// 2: "和键keyFunc关联的值"
console.log(map.entries()) // 0: {"a string" => "和键'a string'关联的值"}
// 1: {Object => "和键keyObj关联的值"}
// 2: {function () { } => "和键keyFunc关联的值"}
map.forEach((value, key, map) => {
console.log(value, key, map)
})
for ([key, value] of map) {
console.log(key, value) //a string 和键'a string'关联的值
// lesson2-3.js:156 {} "和键keyObj关联的值"
// lesson2-3.js:156 ƒ () { } "和键keyFunc关联的值"
}
4.Object和Map键值对的区别
- 键的类型
一个Object的键只能是字符串或者Symbols,但一个Map的键可以任意值,包括函数、对象、基本类型。 - 键的顺序
Map中的键值是有序的,而添加到对象中的键则不是。因此,当对它进行遍历时,Map对象是按插入顺序返回键值。 - 键值对的统计
可以通过size属性直接获取一个Map的键值对个数,而Object的键值对个数只能手动计算。 - 键值对的遍历
Map可以直接进行迭代,而Object的迭代需要先获取它的键数组,然后再进行迭代 - 性能
Map在涉及频繁增删键值对的场景下会有些性能优势。
5.Object.assign()
Object.assign方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象。
const target = { a: 1, b: 2 }
const source = { b: 4, c: 5 }
const returnTarget = Object.assign(target, source)
console.log(target) //{a: 1, b: 4, c: 5}
console.log(returnTarget) //{a: 1, b: 4, c: 5}
从语法上可以看出源对象的个数是无限的(零个或多个),如果是零个直接返回目的对象,如果是多个相同属性的会被后边的源对象的属性覆盖。
let s = Object.assign({ a: 1 })
console.log(s) //{a: 1}
如果目的对象不是对象,则会自动转换为对象。
let t = Object.assign(2)
let s = Object.assign(2, { a: 2 })
console.log(t) //Number {2}
console.log(s) //Number {2, a: 2}