在了解es6装饰器之前, 先了解一下Object.defineProperty()
= 与 Object.defineProperty
为JavaScript 对象新增或者修改属性,有两种不同的方式:
- 直接使用
=
赋值 - 使用Object.defineProperty()定义
如下:
var obj = {}
obj.a = 1;
Object.defineProperty(obj, "b", {
value: 2
})
console.log(obj); //
image.png
这样看两者似乎没有区别,使用 Object.getOwnPropertyDescriptor() 查看 obj.a 与 obj.b的属性的 描述符时, 会发现 = 与 Object.defineProperty并不一样:
console.log(Object.getOwnPropertyDescriptor(obj, "a"));
console.log(Object.getOwnPropertyDescriptor(obj, "b"));
image.png
可知, 使用 = 赋值, 属性的属性描述符 value 是可以修改的, 而writable、enumerable和configurable都为true。
而使用Object.defineProperty()定义的属性的属性描述符writable、enumerable和configurable默认值为false, 导致obj.b属性不能赋值、不能遍历而且不能删除
obj.a = 111;
console.log(obj);
obj.b = 3;
console.log(obj);
image.png
在严格模式下,会报错
如果要使两者等价,需要在Object.defineProperty() 定义时,同时将writable、enumerable和configurable设为true
Object.defineProperty(obj, "b", {
value: 2,
writable: true,
enumerable: true,
configurable: true
})
obj.b = 3;
console.log(obj); // {b:3}
writable
writable为false时, 属性不能再次赋值, 严格模式下会报错“Cannot assign to read only property”
"use strict"
var obj = {}
Object.defineProperty(obj, "b", {
value: 2,
writable: false,
enumerable: true,
configurable: true
})
obj.b = 3;
console.log(obj);
image.png
enumerable
enumerable为false时, 属性不能遍历:
var obj = {}
Object.defineProperty(obj, "b", {
value: 2,
writable: true,
enumerable: false,
configurable: true
})
console.log(Object.keys(obj)); // [] enumerable设为true时,打印["b"]
configurable
configurable为false时,属性不能删除, 严格模式下会报错"Cannot delete property 'b' of #<Object>"
Object.defineProperty(obj, "b", {
value: 2,
writable: true,
enumerable: true,
configurable: false
})
delete obj.b
console.log(obj);
configurable设为true, 可以删除
网友评论