關於js的Object.defineProperty
阿新 • • 發佈:2021-02-12
好久不見,甚是想念
今天你敲程式碼了嘛!?今天我們來聊聊js中的 Object.defineProperty方法,這個可是困擾了我半天,廢話不多說,讓我們來看看吧
首先先上一個連結https://developer.mozilla.org/zh-cn/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
MDN上面寫的挺詳細的,我也就是總結一些比較重要的方法
var obj ={}
object.defineProperty(obj,'a',{
value:4
})
console.log(obj.a)
// 4
那麼上面這段程式碼與下面有什麼區別呢!
var obj ={}
obj.a =4
console.log(obj.a)
//4
然後經過一番的研究
當你修改物件的a屬性時就會發現區別
var obj ={}
object.defineProperty(obj,'a',{
value:4
})
console.log(obj.a)
obj.a = 6
console.log(obj.a)
//4
//4
這是因為Object.defineProperty裡面有個隱藏屬性叫writable
預設為 false
當且僅當該屬性的 writable 鍵值為 true 時,屬性的值,也就是上面的 value,才能被賦值運算子改變。
還有一些比較隱藏的方法,讓我們來看一下
預設為 false
當且僅當該屬性的 enumerable 鍵值為 true 時,該屬性才會出現在物件的列舉屬性中。
var obj ={}
Object.defineProperty(obj,'a',{
value:6,
enumerable:true
})
Object.defineProperty(obj,'b',{
value:7,
enumerable:false
})
for(let n in obj){
console.log(n)
}
//a
get 方法
屬性的 getter 函式,如果沒有 getter,則為 undefined
this
物件(由於繼承關係,這裡的this
並不一定是定義該屬性的物件)。該函式的返回值會被用作屬性的值。預設為 [
undefined
]
Object.defineProperty(obj,'a',{
get(){
console.log('你正在試圖訪問obj的a屬性')
return 4
}
}
Object.defineProperty(obj,'a',{
value:4
}
//console.log(obj.a)
//4
因此get方法 和 直接賦值 的效果是一樣的
但是要注意一件事就是 賦值和get、set方法不能同時使用
var obj ={}
Object.defineProperty(obj,'a',{
value:7,
get(){
console.log('你正在試圖訪問obj的a屬性')
return 4
}
})
console.log(obj.a)
set方法
屬性的 setter 函式,如果沒有 setter,則為 undefined
。當屬性值被修改時,會呼叫此函式。該方法接受一個引數(也就是被賦予的新值),會傳入賦值時的 this
物件。
預設為 **預設為 [undefined
]
var obj = {}
Object.defineProperty(obj,'a',{
get(){
return 8
},
set(n){
console.log('你正在試圖改變obj的a屬性',n)
}
})
obj.a =10
console.log(obj.a)
//8
雖然set方法攔截到了 但是並沒有改變obj.a的值
這是因為
get並沒有返回 新設定的值
因此只要訪問obj.a 就會呼叫get方法,return 8
那麼如何解決這個問題呢!
引入一個變數
var obj = {}
var temp;
Object.defineProperty(obj,'a',{
get(){
console.log('你正在試圖訪問obj的a屬性')
return temp
},
set(n){
console.log('你正在試圖改變obj的a屬性',n)
temp = n
}
})
obj.a =10
console.log(obj.a)
//10
我們還可以將它封裝一下
var obj = {}
function defineReactive(data,key,val){
Object.defineProperty(data,key,{
get(){
console.log('你正在試圖訪問obj的a屬性')
return val
},
set(n){
console.log('你正在試圖改變obj的a屬性',n)
if(val === n){
return
}
val = n
}
})
}
defineReactive(obj,'a',10)
obj.a =70;
console.log(obj.a)
//70