MDN上是這樣解釋的:Object.defineProperty( )方法直接在一個對象上定義新的屬性或修改現有屬性,並返回該對象。 本文快速的講解Object.defineProperty( ),在不少雙向數據綁定的框架,都是基於這個方法去監聽數據的變化的,因此這個Object的方法很重要.因此才用一篇文還在那個來說解這個方法html
當咱們修改(刪除,)一個對象(屬性)時,Object.defineProperty( )能夠能夠攔截你的操做,監聽數據的改變.git
<script>
var obj = {};//對象
Object.defineProperty(obj,'name',{
value:'chenm'
});
console.log(obj.name); //chenm
</script>
複製代碼
obj : 要修改操做的對象 prop: 要定義或修改的屬性的名稱。 descriptor: 將被定義或修改的屬性描述符。github
obj和prop這兩個沒有啥說的 那個我直接開始本方法的關鍵數組
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>
複製代碼
<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>
複製代碼
<!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>
複製代碼
到此結束~~~~~~~~~~~~~~~~~~~~~~