Object.definedProperty 可以給對象添加一個屬性却特,或者修改一個已有的屬性建峭,添加一些配置項
參數(shù)
const obj = {}
/**
* obj 源對象
* prop 要定義或修改的屬性的名稱或 Symbol 症副。
* descriptor 要定義或修改的屬性描述符凌受。
*/
Object.defineProperty(obj, 'a', {
value: 1, // 值
configurable: true, // 當(dāng)且僅當(dāng)該屬性的 configurable 鍵值為 true 時阵子,該屬性的描述符才能夠被改變,同時該屬性也能從對應(yīng)的對象上被刪除胜蛉。 默認(rèn)為 false挠进。
writable: true, // 是否可寫色乾。默認(rèn)為 false
enumerable: true, // 當(dāng)且僅當(dāng)該屬性的 enumerable 鍵值為 true 時,該屬性才會出現(xiàn)在對象的枚舉屬性中领突。默認(rèn)為 false
get() {}, // 獲取值時觸發(fā)
set() {} // 設(shè)置值時觸發(fā)
})
實現(xiàn)對一個對象的監(jiān)聽暖璧,在訪問屬性、設(shè)置屬性時君旦,打印出 'get xx attr' 'set xx attr'
var object = {
a: 1,
b: 2
}
for(let key in object) {
let value = obj[key]
Object.defineProperty(object, key, {
configurable: true,
enumerable: true,
get() {
console.log(`get ${key} attr`)
return value
},
set(newValue) {
console.log(`set ${key} attr`)
value = newValue
}
})
}
object.a // get a attr
object.b = 3 // ser a atter 設(shè)置值的時候并不會觸發(fā) get 方法
設(shè)置值的時候并不會觸發(fā) get 方法
實現(xiàn)類似 Vue 的響應(yīng)式代理
如訪問 this.a 實際訪問的是 this.$data.a
var Vue = {
$data: {
a: 1,
b: 2
}
}
for(let key in Vue.$data) {
let value = Vue.$data[key]
Object.defineProperty(Vue, key, {
configurable: true,
enumerable: true,
get() {
return Vue.$data[key]
},
set(newValue) {
Vue.$data[key] = newValue
}
})
}
console.log(Vue.a, Vue.$data.a) // 1, 1
Vue.a = 2
console.log(Vue.a, Vue.$data.a) // 2, 2
Vue.$data.b = 3
console.log(Vue.b, Vue.$data.b) // 3, 3
簡單實現(xiàn) Vue 中對數(shù)組的劫持處理
var arr = [1, {a: 1}, 3]
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] === 'object' && arr[i] !== null) {
for (let key in arr[i]) {
let value = arr[i][key]
Object.defineProperty(arr[i], key, {
configurable: true,
enumerable: true,
get() {
console.log(`get ${key} attr`)
return value
},
set(newValue) {
console.log(`set ${key} attr`)
value = newValue
}
})
}
}
}
// arrPro 一個橋梁攔截了原生的 push 方法澎办,然后在調(diào)用原生的 push
// 攔截是因為防止原型鏈污染
var arrPro = Object.create(Array.prototype)
arr.__proto__ = arrPro
arrPro.push = function(argu) {
if (typeof argu === 'object' && argu !== null) {
for (let key in argu) {
let value = argu[key]
Object.defineProperty(argu, key, {
configurable: true,
enumerable: true,
get() {
console.log(`get ${key} attr`)
return value
},
set(newValue) {
console.log(`set ${key} attr`)
value = newValue
}
})
}
}
arrPro.__proto__.push.call(this, argu)
}
arr[0] = 0
arr[1].a = 'a'
// 使得添加的數(shù)據(jù)成響應(yīng)式
arr.push({b: 2})
【筆記不易,如對您有幫助金砍,請點贊局蚀,謝謝】