外观
ES6 给对象加了什么?
属性可以简写,方法可以写进字面量,键可以是表达式。合并用展开或 Object.assign,但两者都是浅拷贝。
原理
js
const name = "a"
const obj = {
name,
greet() {},
["id_" + name]: 1
}Object.assign(target, ...sources) 把源对象的可枚举自身属性拷到目标上,后面的同名属性覆盖前面的。它会改第一个参数。不想改原对象就从 {} 开始,或用 { ...a, ...b }。
Object.keys、values、entries 只包含可枚举的自身字符串键。Symbol 键用 Object.getOwnPropertySymbols 或 Reflect.ownKeys。
属性描述符用 Object.defineProperty、getOwnPropertyDescriptor。Object.freeze 冻结自身属性,嵌套对象仍然可改。
追问
展开和 Object.assign 的差别?
结果都是浅拷贝。展开不复制原型上的属性,也不触发 setter 作为写入目标时的特殊行为那么多;Object.assign 会调用源对象的 getter、目标对象的 setter。两者都会把只读属性的值读出来再写到新对象上。
怎么做不可变更新?
改一层用展开:{ ...user, name }。改嵌套要每一层都展开。层级深、更新频繁时再用不可变库,不要为了一个字段引入一套结构共享。
易错点
- 展开和
assign都不是深拷贝。嵌套对象仍是同一引用。 Object.keys看不到Symbol,也看不到不可枚举属性。freeze不是深冻结。