快速理解Object.defineProperty( )

原文地址

关于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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值