JavaScript进阶之' Object.defineProperty( ) '

MDN上是这样解释的:Object.defineProperty( )方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。 本文快速的讲解Object.defineProperty( ),在很多双向数据绑定的框架,都是基于这个方法去监听数据的变化的,所以这个Object的方法很重要.所以才用一篇文还在那个来讲解这个方法

本人Object.defineProperty( )对理解

当我们修改(删除,)一个对象(属性)时,Object.defineProperty( )可以可以拦截你的操作,监听数据的改变.

先看代码
<script>
	var obj = {};//对象
	Object.defineProperty(obj,'name',{
	    value:'chenm'
	});
	console.log(obj.name); //chenm
</script>
复制代码
语法 Object.defineProperty(obj, prop, descriptor)

obj : 要修改操作的对象 prop: 要定义或修改的属性的名称。 descriptor: 将被定义或修改的属性描述符。

objprop这两个没有啥说的 那个我直接开始本方法的关键

descriptor属性描述符

MDN这样说: 对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

说的太啰嗦,我都不想读,我给大家画个图(一下你就明白了)

注意 数据描述符的 (writable value) 和 存取描述(get,set) 只能够存在一种

 <script>
      var obj = {};
      Object.defineProperty(obj, "key", {
          enumerable: false,
          configurable: false,
          writable: false,
          value: "static",

          get: function () {
          },
          set: function (newValue) {
          },
      });
      //会报错
      // throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors
</script>
复制代码

value:定义该属性的值,默认为 undefined。

<script>
	var obj = {};
	 Object.defineProperty(obj, "key", {
	      value: 123456
	  });
	  console.log(obj.key)//输出//456
 </script>
复制代码

configurable:为 true 时,该属性描述符才能够再次被改变,同时该属性也能从对应的对象上被删除。默认为 false。

<script>
      var obj = {};
      Object.defineProperty(obj, "key", {
      	  value: 123456,
          configurable: false
      });
      delete obj.key; 
      console.log(obj.key); //123456
      //configurable: false时删除无效,所以打印还是123456
</script>
复制代码
configurable: true
<script>
      var obj = {};
      Object.defineProperty(obj, "key", {
      	  value: 123456,
          configurable: true
      });
      delete obj.key; 
      console.log(obj.key); //undefined
      //configurable: true 时删除成功,所以打印还是undefined
</script>
复制代码

enumerable:为true时,该属性才能够出现在对象的枚举属性中。默认为 false。

这里说一下枚举,是可以被 for...in 循环和 Object.keys() 查找出来

** 一下引用自掘金:化身孤岛的鲸...写的很不错直接借鉴一下) **

<script>
//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"]
</script>
复制代码

writable:为true时,属性的值才能被 ‘=’ 赋值运算符赋值。默认为 false。

<script>
//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
</script>
复制代码

get: 一个给属性提供 getter 的方法。当访问(获取)该属性时,该方法会被执行。 set: 一个给属性提供 setter 的方法。当修改该属性值时,该方法会被执行。

<script>
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
</script>
复制代码
<script>
//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
</script>
复制代码
根据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>

复制代码

到此结束~~~~~~~~~~~~~~~~~~~~~~

作者

作者: weshmily科技站长
官网: 百度搜索(weshmily科技)
CSDN博客:blog.csdn.net/qq_27118895
gihub地址:github.com/weshmily
公众号:搜索"weshmilyqd"

转载于:https://juejin.im/post/5d10e82ff265da1bb13f3e1c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值