JavaScript進階之' Object.defineProperty( ) '

在這裏插入圖片描述

MDN上是這樣解釋的:Object.defineProperty( )方法直接在一個對象上定義新的屬性或修改現有屬性,並返回該對象。 本文快速的講解Object.defineProperty( ),在不少雙向數據綁定的框架,都是基於這個方法去監聽數據的變化的,因此這個Object的方法很重要.因此才用一篇文還在那個來說解這個方法html

本人Object.defineProperty( )對理解

當咱們修改(刪除,)一個對象(屬性)時,Object.defineProperty( )能夠能夠攔截你的操做,監聽數據的改變.git

先看代碼
<script>
	var obj = {};//對象
	Object.defineProperty(obj,'name',{
	    value:'chenm'
	});
	console.log(obj.name); //chenm
</script>
複製代碼

語法 Object.defineProperty(obj, prop, descriptor)

obj : 要修改操做的對象 prop: 要定義或修改的屬性的名稱。 descriptor: 將被定義或修改的屬性描述符。github

objprop這兩個沒有啥說的 那個我直接開始本方法的關鍵數組

descriptor屬性描述符

MDN這樣說: 對象裏目前存在的屬性描述符有兩種主要形式:數據描述符和存取描述符。數據描述符是一個具備值的屬性,該值多是可寫的,也可能不是可寫的。存取描述符是由getter-setter函數對描述的屬性。描述符必須是這兩種形式之一;不能同時是二者。app

在這裏插入圖片描述

說的太囉嗦,我都不想讀,我給你們畫個圖(一下你就明白了)

在這裏插入圖片描述

注意 數據描述符的 (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。spa

<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。.net

這裏說一下枚舉,是能夠被 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"

相關文章
相關標籤/搜索