一、ES5中Object属性可以简写吗?ES6可以吗?
// ES6之前 Object 属性必须是 key-value 形式
let x = 1;
let y = 2;
let z = 3;
let obj = {
x: x,
y: y
}
//在 ES6 之前 Object 的 key 在定义时必须是字符串,如果想增加“动态”的 key,必须是先计算出 key,利用 object[key] = value 的方式来修改,例如:
obj[z] = 6
console.log(obj);// {x: 1, y: 2, 3: 6}
// ES5 之前 Object 的属性只支持常规函数,对于异步函数是不支持的
// ES6可以简写为
let x = 1;
let y = 2;
let z = 3;
let obj = {
x,
y,
[z]: 6, // 属性值支持变量 {3: 6}
[x+z]: 7, // 属性值支持表达式 {4: 7}
say() { // 函数:常规函数
console.log('hello')
},
* eat() { // 函数:异步函数
console.log('food')
},
//function* eat(){} //等同于上面的写法
}
二、新的数据结构 Set
在 JavaScript 里通常使用 Array 或 Object 来存储数据。但是在频繁操作数据的过程中查找或者统计并需要手动来实现,并不能简单的直接使用。比如如何保证 Array 是去重的,如何统计 Object 的数据总数等,必须自己去手动实现类似的需求,不是很方便。在 ES6 中为了解决上述痛点,新增了数据结构 Set 和 Map,它们分别对应传统数据结构的“集合”和“字典”。
let s = new Set();
// let s = new Set([1, 2, 3, 4]); // set 可接收的参数必须是一个可遍历对象 Inferable Object
s.add('hello');
s.add('goodbye');
s.add('a').add('b'); // 可链式操作
console.log(s) // {"hello", "goodbye", "a", "b"}
s.add('a').add('c');
console.log(s) // {"hello", "goodbye", "a", "b", "c"} 传入重复的数据会自动过滤
s.delete('hello') //删除指定数据
// s.clear() // 删除所有数据
s.has('hello') // 此返回返回布尔值,可快速得知set里是否有某数据
s.size // 此属性返回目前 set 存入数据的长度
console.log(s.keys()) // SetIterator {"goodbye", "a", "b", "c"} 返回键遍历器
console.log(s.values()) // SetIterator {"goodbye", "a", "b", "c"} 返回值遍历器
console.log(s.entries()) // SetIterator {"goodbye" => "goodbye", "a" => "a", "b" => "b", "c" => "c"} 返回键值对遍历器
// forEach 遍历set
s.forEach(item => {
console.log(item)
})
// for...of 遍历set
for(let item of s){
console.lot(item)
}
三、新的数据结构 Map
Map 实现字典的功能(Object 键值对)
//初始化 map
let map = new Map([
[1, 2],
[3, 4]
]);
console.log(map) // Map(2) {1 => 2, 3 => 4}
let map = new Map();
map.set(1, 2) // Map(1) {1 => 2} 添加数据
map.set(1, 3) // Map(1) {1 => 3} 修改数据
map.set(2, 4) //
map.delete(1) // Map(1) {2 => 4} 删除指定数据
//map.clear() // 删除全部数据
console.log(map.size) // 1 统计map数据长度
console.log(map.has(1)) //false 查找数据,查找的是key
console.log(map.get(2)) // 4 返回指定key的value
map.set(3, 6)
console.log(map.keys()) // MapIterator {2, 3} 返回一个新的 Iterator 对象,它包含按照顺序插入 Map 对象中每个元素的 key 值
console.log(map.values()) // MapIterator {4, 6} 返回一个新的 Iterator 对象,它包含按顺序插入Map对象中每个元素的 value 值
console.log(map.entries()) // MapIterator {2 => 4, 3 => 6} 返回一个新的包含 [key, value] 对的 Iterator 对象,返回的迭代器的迭代顺序与 Map 对象的插入顺序相同
console.log(map)
map.forEach((value, key) => { // 切记:forEach遍历参数,先value后key
console.log(value, key)
})
for (let [key, value] of map) { // for...of 后的对象必须是可遍历的,按初始化/添加顺序遍历
console.log(key, value)
}
WeakSet 和Set的区别:存储的数据只能是对象
WeakMap和Map的区别:只允许接收对象类型的key
四、ES5中怎样把一个对象复制到另一个对象上?ES6如何实现?
// ES6 Object.assign()
const target = {
a: {
b: {
c: {
d: 9
}
},
e: 5,
f: 6,
h: 10
}
}
const source = {
a: {
b: {
c: {
d: 1
}
},
e: 2,
f: 3
}
}
Object.assign(target, source); // 参数:接收对象,源对象 assign 实现的是浅拷贝
// 浅拷贝:对于基本类型数据作数据替换,对于引用类型数据不再遍历,而是替换引用地址
// 解决方案:判断如果是引用类型数据,递归
console.log(target) // {b: 4, c: 5}
思考:
1、如果目标对象传入的是 undefined 和 null 将会怎样呢?
2、如果源对象的参数是 undefined 和 null 会怎样呢?
3、如果目标对象是个嵌套的对象,子对象的属性会被覆盖吗?