最近在看 Nest.js ,发现还是有不少好玩的东西,比如装饰器。
Proxy, Reflect, Object.defineProperty 等都有用到。
为了加强理解,通过这一篇来记录 Object.defineProperty
的用法
Object.defineProperty
Object.defineProperty(obj, prop, descriptor)
参数含义
obj 要定义属性的对象
prop 要定义或修改的属性的名称
descriptor 要定义或修改的属性描述符。
描述
属性描述符有两种主要形式,存取描述符,数据描述符
存储描述符
getter settter
数据描述符
- configurable
- enumerable
- value 【不能与 getter, setter 同时用】
- writable 【不能与 getter, setter 同时用】
定义新的属性
const obj = {};
Object.defineProperty(obj, "name", {
value: "chen xiaochi",
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.name);
运行结果
> chen xiaochi
我们可以配置属性 wrtiable 为 false, 然后尝试赋值 mimeay
const obj = {};
Object.defineProperty(obj, "name", {
value: "chen xiaochi",
writable: false,
enumerable: true,
configurable: true
});
obj.name = "mimeay"
console.log(obj.name);
运行结果没报错,输出还是
> chen xiaochi
如果想要报错的话,可以在文件开始标明使用 use strict
"use strict";
const obj = {};
Object.defineProperty(obj, "name", {
value: "chen xiaochi",
writable: false,
enumerable: true,
configurable: true
});
obj.name = "mimeay"
console.log(obj.name);
运行结果则会提示如下
> Uncaught TypeError: Cannot assign to read only property 'name' of object '#'
Enumerable
enumerable 属性定义了该字段是否可被枚举
const obj = {};
Object.defineProperty(obj, "name", {
value: "chen xiaochi",
writable: false,
enumerable: true,
configurable: true
});
console.log(Object.keys(obj))
for(let i in obj) {
console.log(i)
}
输出结果
> ["name"]
> name
而当 enumerable
为 false
的时候,在 for in , Object.keys 都是不会被枚举到
const obj = {};
Object.defineProperty(obj, "name", {
value: "chen xiaochi",
writable: false,
enumerable: false,
configurable: true
});
console.log(Object.keys(obj))
for(let i in obj) {
console.log(i);
}
点运算符定义属性的枚举默认值
用点运算符定义的属性,默认是可枚举的。
const obj = {};
obj.age = 18;
console.log(obj.age)
console.log(obj.propertyIsEnumerable("age"))
运行结果
> 18
> true
如果需要设置不可枚举, 则通过以下方式设置 即可
Object.defineProperty(obj, "age", {
enumerable: false
})
以上例子均在 http://js.jsrun.net/new 验证, 参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty 进行示例
网友评论