文章目录
一. Object.defineProperty
1. MDN文档
2. 用途
Object.defineProperty用于给对象添加新属性或者修改原有属性。
3. 具体使用
1. 参数
Object.defineProperty(obj, prop, descriptor)
// Object.defineProperty(对象, 属性名, 属性描述符)。
2. 使用
例如,现有一个person对象,包括人名和性别。
let person = {
"name": "张三",
"sex": "男"
}
现在添加新属性年龄,年龄21岁。
- 常规方法
person.age = 21;
- defineProperty
Object.defineProperty(person, "age", {
value: 21
})
- 区别:
- 常规方法直接定义的age是
可枚举
的,而defineProperty定义的age默认是不可枚举
的。 - 常规方法直接定义的age是
可修改
的,而defineProperty定义的age默认是不可修改
的。 - 常规方法直接定义的age是
可删除
的,而defineProperty定义的age默认是不可删除
的。
原因是描述符的默认值都是false。
3. 属性描述符
属性描述符顾名思义,就是用来描述刚刚添加的属性的,也就是给刚刚添加的属性添加一些限制条件。
- 查看defineProperty的文档,可以知道属性描述符分两种,数据描述符和存取描述符。
- 数据描述符有4种对于属性的描述。
- value: 属性值。
- enumerable:该属性是否可枚举。默认值
false
。 - writable:该属性是否可修改。默认值
false
。 - configurable:字面理解-该属性是否可以被配置。默认值
false
。
MDN:仅当configurable值为true时,属性描述符能够被修改,同时该属性也能被从对象上删除。
就是当configurable值为true的时候,可以修改enumerable、writable、configurable的值,也可以删除该属性。
- 存取描述符
配置get\set函数。
(有点类似JavaBean的get、set方法,通过私有成员变量加get、set的方式,控制对于成员变量的获取、修改。利用get、set加一层代理,可以避免外围代码对于变量的直接访问,提高安全性,例如可以在set中加数据校验。当然也可以get中加数据处理操作。)let person = { "name": "张三", "sex": "男" } Object.defineProperty(person, "age", (function(){ let age = 21; return { enumerable: true, // 是否可枚举, 默认值false configurable: false, // 是否可删除,默认值false get: function() { return age + 2; }, set: function(value) { if (typeof value === "number") { age = value; } else { throw("TypeError") } } } })() )
- 描述符可拥有的键值
表中可以发现,(writable、value)和(get、set)不可以同时设置。configurable enumerable writable value get set 数据描述符 可以 可以 可以 可以 不可以 存取描述符 可以 可以 不可以 不可以 可以
二、Object.defineProperties
1. MDN文档
2. 用途
在对象上定义新的属性或修改现有属性并返回该对象。
可以认为是一次设置多个属性。
3. 使用
- Object.defineProperties(obj, props)
- props是(属性名:属性描述符)的键值对集合。
let person = {};
Object.defineProperties(person, {
"name": {
value: "张三",
writable: true,
enumerable: true
},
"gender": {
value: "男",
writable: true,
enumerable: true
},
"age": (function() {
age = 18;
return {
enumerable: true,
configurable: true,
get: function() {
return age + 2;
},
set: function(value) {
if (typeof value === "number") {
age = value;
}
else {
throw "TypeError";
}
}
}
})()
})
console.log(person)