对象的扩展
对象的属性
- 属性的简写操作:
{a, b} <=> {a: a, b: b}
,其中:- 属性名为变量名a,属性值为变量a的值
- 属性的赋值器set和取值器get使用的也是简写操作
- 方法的简写操作:
foo () {} <=> foo: function () {}
- 简写的对象方法不能用做构造函数,会报
TypeError: a.f is not a constructor
- 判断一个值是否能成为构造函数的方式为:该值必须是对象,且内部含有constructor方法【参考】(可在console中进行验证:判断value.prototype是否是一个含有constructor方法的对象即可,自我测试的)
- 简写的对象方法不能用做构造函数,会报
- 属性名表达式:obj[expression] = value/fn
- expression为一个表达式
- 属性名表达式不能和属性的简写一起使用,会报错
- 属性名表达式若是一个对象,则该属性名直接为
[object object]
- 函数/方法的name属性:
- 返回该函数/方法的名字
- 若对象方法设置了get/set函数,则name的值为该方法的属性描述对象的get/set方法上,返回值为方法名前面加上get/set:
Object.getOwnPropertyDescriptor(obj, 'foo').get/set.name
- bind方法创建的函数,返回
bound fname
- Function构造函数创建的函数,返回
anonymous
- 对象方法是一个symbol值,则返回这个symbol的描述
- 可枚举性(属性描述对象:
Object.getOwnPropertyDescriptor(obj, property)
的enumerable属性)设置了该属性会忽略以下操作:- for...in:仅仅遍历继承的和对象自身的可枚举属性
- Object.keys()、JSON.stringify()、Object.assign():仅遍历对象自身的可枚举属性
- 属性的遍历操作还有:遍历自身非symbol的属性
Object.getOwnPerprotyNames()
、遍历自身的symbol属性Object.getOwnPerprotySymbols()
、遍历所有属性Reflect.ownKeys()
- 上述遍历键名的方法规则如下:先遍历数值键(数值升序)、遍历字符串键(加入时间升序)、遍历symbol键(加入时间升序)
- super关键字:指向对象的原型
- 当super表示原型对象时,只能用在对象的方法(仅指方法的简写)中,只有它能够让js引擎确认定义的是对象的方法
super.foo <=> Object.getPrototypeOf(this).foo <=> Object.getPrototypeOf(this).foo.call(this)
- 设置对象的原型:
Object.setPrototypeOf(obj, proto)
- 获取对象的原型:
Object.getPrototypeOf(obj)
- 扩展运算符,公式:
{ ...reset, ...reset2, ... } <=> Object.assign({}, reset, reset2, ...}
,有以下注意:- reset为字符串/数组时,会生成一个以索引为键的对象
- reset为空对象、
null、undefined、Boolean、Number
(自动转为包装对象)时,返回为{}
- reset可以是一个表达式
- reset中若有get取值函数,该取值函数是会自动执行的
- 可多个对象一起使用:
{ ...reset1, ...reset2 }
,后面的属性会覆盖前面的,所以可以:- 用于修改对象的属性
{ ...obj, name: 'new name' }
- 对对象设置默认值:
{ name: 'default name', ...obj }
- 用于修改对象的属性
- 克隆完整对象的方法,包括对象原型属性🌹
- 链判断运算符
?.
:在链式调用的时候判断左侧对象是否为null/undefined,若是,则返回undefined,不在往下计算- 三种使用方法:
- 对象属性:
obj?.attr
,obj?.[attr]
- 函数/对象方法:
func?.()
,obj.method?.()
- 对象属性:
- 注意:
- 短路机制:当链判断不符合时,立即返回,不继续计算
- delete操作:当链判断不符合时,不进行delete操作
- 圆括号的影响:若链判断在圆括号内部,其后的操作不影响,例如:
(a?.b).c
,c始终会被调用 - 右侧不得为十进制数,否则会被当成三元运算符处理:
a?.10:0 => a ? 0.10 : 0
- 报错场合:用在构造函数中、链判断右侧有模板字符串、链判断左侧为super、链判断用于赋值左侧
- 三种使用方法:
- Null判断运算符
??
:解决的是左侧值仅为null/undefined时(非其他假值),返回右侧的值- 适合用于参数是否赋值
- 适合跟链判断运算符一起使用
- 当与
&&
,||
一起使用时,必须用括号括起最先执行的,以表明他们的顺序
javascript
// 🌹
// 第一种:非浏览器环境下可能无效,不推荐
const clone1 = {
_proto_: Object.getPrototypeOf(obj),
...obj
}
// 第二种:
const clone2 = Object.assign({
Object.create(Object.getPrototypeOf(obj)),
obj
})
// 第三种:
const clone3 = Object.create(
Object.getPrototypeOf(obj),
Object.getpropertyDescriptors(obj)
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
妙用
- 打印多个对象时,为了方便确认,可使用属性的简写形式,将多个对象放在一个大括号内:
console.log({obj1, obj2})