defineProperty方法的使用
defineProperty 是静态方法,由构造函数调用
作用:给实例对象定义属性
首先让我们来看一个例子:
let zs = {
uname:'张三',
age:18
}
zs.weight='65kg'
console.log(zs)//{uname: '张三', age: 18, weight: '65kg'}
由此可见,我们可以给zs这个对象添加一个weight属性,那么我们在看看下面的例子:
let zs = {
uname:'张三',
age:18
}
Object.defineProperty(zs, 'weapon', {
value: '民法典',//通过value,可以动态地将obj对象的属性动态地添加给zs中
enumerable: false, //定义属性是否可枚举,默认值是false,也就是不可枚举
writable: false, //定义属性是否可改变,默认值是false,也就是不可改变
configurable: false //定义属性是否可删除,默认值是false,也就是不可删除
})
console.log(zs.weapon);
// 判断是否可枚举
for (let key in zs) {
console.log(key);
}
console.log(Object.keys(zs))
// 判断是否可改变
zs.age = 55
console.log(zs);
zs.weapon = '法典'
console.log(zs);
// 判断属性是否可删除
delete zs.age
console.log(zs);
delete zs.weapon
console.log(zs);
我们会发现我们不能对zs这个对象进行枚举,改变,删除了,这是我们只要把defineProperty方法里面的对应属性值改成true就可以操作了。上面是defineProperty方法的四个属性的使用,下面我们再看看defineProperty方法里面的两个方法get,set。
当设置get,set方法时,不能有value和writable方法,否则会报错
set方法只有在设置/修改指定属性值的时候,才会触发,即调用set下的匿名函数
let swk = {
uname: '孙悟空',
}
// private私有属性,约定俗成的命名方式是: 下划线_属性名 , 后续如果看到对象中存在这种形式的属性,不需要操作
Object.defineProperty(swk, '_age', {
value:500,
// enumerable: false //默认值可以不写
writable:true,
// configurable: false //默认值可以不写
})
// 第三个参数是存取描述符
Object.defineProperty(swk,'age',{
// getter取值方法,访问对象的该属性的时候会被调用
get:function(){
// console.log(this); //指向的是swk
console.log('取值方法被调用了');
return this._age
},
// setter赋值方法,在给对象的age属性赋值的时候会被调用
set:function(val){
console.log('赋值方法被调用了');
if(val>1000) return
this._age=val
},
enumerable:true,
configurable:true
// value:10000, value和writable属性在存取描述符中是不可使用的
// writable:true
})
console.log(swk.age);
swk.age=1001
console.log(swk.age); //500,因为在赋值方法中限制了赋值的范围不能大于1000
console.log(Object.keys(swk));
console.log(swk);