MDN解釋:
Object.defineProperty()
方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。html
本文簡單的講解了 Object.defineProperty
有助於你快速瞭解 Object.defineProperty
想要詳細學習請移至MDN文檔數組
個人理解就是 當你操做一個對象(修改或者刪除屬性)時,Object.defineProperty能夠控制是否能夠去操做這個對象(修改、刪除屬性)或者修改、獲取屬性值時攔截你的操做而後do something。bash
Object.defineProperty(obj, prop, descriptor)
obj 要操做的對象
prop 要定義或修改的屬性的名稱
descriptor 將被定義或修改的屬性描述符
複製代碼
先看一下基本使用,而後下面會具體講解一下屬性描述符。ide
var obj = {};
Object.defineProperty(obj,'name',{
value:'chenm'
});
console.log(obj.name); //chenm
複製代碼
分爲數據描述符和存取描述符
學習
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
複製代碼
注意:ui
//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()添加的屬性,描述符的默認值是有所的同的。this
現有屬性描述符默認值:
configurable:true
enumerable:true
writable:true
Object.defineProperty()添加的屬性描述符默認值:
configurable:false
enumerable:false
writable:false
複製代碼
<!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>
複製代碼
路過點個贊呦~~spa