关于Object.defineProperty()
MDN解释:
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
本文简单的讲解了 Object.defineProperty
有助于你快速了解 Object.defineProperty
想要详细学习请移至MDN文档
我的理解就是 当你操作一个对象(修改或者删除属性)时,Object.defineProperty可以控制是否可以去操作这个对象(修改、删除属性)或者修改、获取属性值时拦截你的操作然后do something。
语法 Object.defineProperty(obj, prop, descriptor)
obj 要操作的对象
prop 要定义或修改的属性的名称
descriptor 将被定义或修改的属性描述符
先看一下基本使用,然后下面会具体讲解一下属性描述符。
var obj = {};
Object.defineProperty(obj,'name',{
value:'chenm'
});
console.log(obj.name); //chenm
descriptor属性描述符
分为数据描述符和存取描述符
configurable:为 true 时,该属性描述符才能够再次被改变,同时该属性也能从对应的对象上被删除。默认为 false。
enumerable:为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
value:该属性的值,默认为 undefined。
writable:为true时,属性的值才能被 ‘=’ 赋值。默认为 false。
get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问(获取)该属性时,该方法会被执行,方法执行时没有参数传入,
但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
set:一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当修改属性值时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
configurable:为 true 时,该属性描述符才能够再次被改变,同时该属性也能从对应的对象上被删除。默认为 false。
//1.configurable为false
var obj = {age:25};
Object.defineProperty(obj,'name',{
configurable:false,
value:'chenm'
});
delete obj.name;
console.log(obj.name); //chenm
//configurable 为false时(当然默认就为false),name不允许被删除,所以打印obj.name 还是chenm
//注意当操作对象现有属性的时候 configurable默认为true
//2.configurable为 true
Object.defineProperty(obj,'age',{
value:'26'
});
delete obj.age;
console.log(obj.age); //undefined
enumerable:为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
//1.enumerable为false
var obj = {age:25};
Object.defineProperty(obj,'name',{
enumerable:false,
value:'chenm'
});
for(let key in obj){
console.log(key) //age
}
console.log(Object.keys(obj))//["age"]
//Object.keys:返回该对象可枚举属性组成的数组。 enumerable为false时,name并不能枚举。
//注意当操作对象现有属性的时候 enumerable默认为true
//2.enumerable为true
var obj = {age:25};
Object.defineProperty(obj,'name',{
enumerable:true,
value:'chenm'
});
for(let key in obj){
console.log(key) //age name
}
console.log(Object.keys(obj)) //["age","name"]
value:该属性的值,默认为 undefined。
var obj = {};
Object.defineProperty(obj,'name',{
value:'chenm'
});
console.log(obj.name); //chenm
Object.defineProperty(obj,'sex',{
});
console.log(obj.sex); //undefined
//不设置value时 改属性的值为 undefined
writable:为true时,属性的值才能被 ‘=’ 赋值。默认为 false。
//1.writable为false
var obj = {};
Object.defineProperty(obj,'sex',{
writable:false,
value:'boy'
});
console.log(obj.sex); //boy
obj.sex = 'girl';
console.log(obj.sex); //boy
//writable 为false(默认就为false),sex是不能用'='赋值的。
//2.writable为true
var obj = {};
Object.defineProperty(obj,'sex',{
writable:true,
value:'boy'
});
console.log(obj.sex) //boy
obj.sex = 'girl'
console.log(obj.sex) //girl
get:一个给属性提供 getter 的方法。当访问(获取)该属性时,该方法会被执行。
set:一个给属性提供 setter 的方法。当修改该属性值时,该方法会被执行。
var obj = {};
let val = '15k';
Object.defineProperty(obj,'wages',{
get:function(){
//这是里获取属性的时候执行
console.log('我获取到你的值了。。。')
return val;
},
set:function(newVal){
//这是里修改属性值的时候执行
console.log('我修改了你的值。。。')
val = newVal
}
});
console.log(obj.wages);
obj.wages = '20k'
console.log(obj.wages);
//我获取到你的值了。。。
//15k
//我修改了你的值。。。
//我获取到你的值了。。。
//20k
//get,set一起出现,如果省略get,获取到的值都是undefined
var obj = {};
let val = '15k';
Object.defineProperty(obj,'wages',{
set:function(newVal){
//这是里修改属性值的时候执行
console.log('我修改了你的值。。。')
val = newVal
}
});
console.log(obj.wages) //undefined
obj.wages = '20k'
console.log(obj.wages)//undefined
//如果省略set, 无法赋值。
var obj = {};
let val = '15k';
Object.defineProperty(obj,'wages',{
get:function(){
//这是里获取属性的时候执行
console.log('我获取到你的值了。。。')
return val;
},
});
console.log(obj.wages) //15k
obj.wages = '20k'
console.log(obj.wages)//15k
注意:
//get,set与writable,value不能共用
var obj = {};
let val = '15k';
Object.defineProperty(obj,'wages',{
value:'20k'
set:function(newVal){
//这是里修改属性值的时候执行
console.log('我修改了你的值。。。')
val = newVal
}
});
//Uncaught SyntaxError: Unexpected identifier
tips:操作对象的现有属性和用Object.defineProperty()添加的属性,描述符的默认值是有所的同的。
现有属性描述符默认值:
configurable:true
enumerable:true
writable:true
Object.defineProperty()添加的属性描述符默认值:
configurable:false
enumerable:false
writable:false
根据Object.defineProperty()的get,set写一个简单的数据双向绑定。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="text" id="input"/>
<span id="text"></span>
<button id="btn1">获取值</button>
<button id="btn2">修改值</button>
<script>
var obj = {
value:123
};
//初始化赋值
document.getElementById('input').value = obj.value;
document.getElementById('text').innerHTML = obj.value;
//监听input方法
document.getElementById('input').oninput = function(e){
obj.value = e.target.value;
};
//使用Object.defineProperty设置属性的get,set方法。
let val = obj.value;
Object.defineProperty(obj,'value',{
get:function(){
return val
},
set:function (newVal){
//当值被修改的时候 修改input&span的值
document.getElementById('input').value = newVal;
document.getElementById('text').innerHTML = newVal;
val = newVal;
}
});
document.getElementById('btn1').onclick = function (){
console.log(obj)
}
document.getElementById('btn2').onclick = function (){
obj.value = '修改了';
}
</script>
</body>
</html>
网友评论