此时我们拥有一个对象 Person,想要对它进行如下一些操作:
1:增加新的属性“sex”。
2:想修改它的age属性。
3:遍历/枚举Person的属性。
let Person = {
name:"石昊",
age: 18
}
Person.sex = "男"; //验证第一条
Person.age = 20; //验证第二条
console.log(Object.keys(Person)); //验证第三条
console.log(Person);
有些同学会觉得这也太简单了,小菜一碟。
那现在我们对上述操作加大难度:
1:增加新的 “sex”属性 ---- 不可遍历/枚举。
2:sex属性值不可以被修改。
3:sex属性值不可以被删除。
直接对Person对象进行操作就不能够满足我们的需求。这时候就有请我们的 Object.defineproperty 隆重登场
let Person = {
name:"石昊",
age: 18
}
Object.defineProperty(Person,'sex',{
value:"男", //设置属性值
enumerable:false, //控制属性是否可以枚举,默认值是false
writable:false, //控制属性是否可以被修改,默认值是false
configurable:false //控制属性是否可以被删除,默认值是false
})
console.log(Object.keys(Person)); //验证第一条
Person.sex = '女'; //验证第二条
delete Person.sex; //验证第三条
console.log(Person);
我们再来加大难度:
对于不可修改的sex属性,我们还是有强烈修改的意愿,这时候我们可以怎么做呢?
let gender = '男';
let Person = {
name:"石昊",
age: 18
}
Object.defineProperty(Person,'sex',{
//当有人读取Person的sex属性时,get函数(getter)就会被调用,且返回值就是sex的值
get(){
console.log("读取sex属性");
return gender;
},
//当有人修改Person的sex属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value){
console.log("修改sex属性,由",gender,"修改为",value);
gender = value;
}
})
console.log(Person);
console.log(Person.sex);
Person.sex = '女';
可以看到,对于不能修改的age属性,我们通过getter setter函数进行了修改。这时我们访问一下声明的gender,会发现 gender也变成了'女'。
是不是很熟悉!vue的双向数据绑定是不是就这么实现的呢,我们又发现了新大陆。
总结
Object.defineproperty(obj, prop, desc)
obj :对象名称,要在哪个对象身上添加或者修改属性
prop :属性名,添加或修改的属性名
desc :配置项,一般是一个对象,可以有多个配置项
配置项如下:
value | 设置属性值 |
enumerable | 控制属性是否可以枚举,默认值是false |
writable | 控制属性是否可以被修改,默认值是false |
configurable | 控制属性是否可以被删除,默认值是false |
get | 读取时内部函数调用 |
set | 写入时内部调用函数 |