Object.defineProperty的基本使用
如何实现一个对象属性监听?
var data = {
a: 1,
b: {
b1: 2
},
}
一个简单的对象,如何在改变它的某个属性值是监听得到当前属性,例如:
对某个元素进行操作时打印set xxx = xxx
data.a = 'a' //set a = a
data.b.b1 = 'b' // set b1 = b
Object.defineProperty
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
语法:
Object.defineProperty(obj, prop, descriptor)
参数:
obj
要定义属性的对象。
prop
要定义或修改的属性的名称或 Symbol 。
descriptor
要定义或修改的属性描述符。
返回值
被传递给函数的对象。
代码示例
var data = {
a: 1
}
Object.defineProperty(data, 'a', {
get: () => {
return value
},
set: (v) => {
value = v
console.log(`set a = ${v}`);
}
})
data.a = 'a'
此时运行后显示
如何监听多层对象?
初始化一个复杂对象:
var data = {
a: 1,
b: {
b1: 2,
b2: {
b31: 4,
b32: 5
}
},
c: 3
}
写一个方法进行遍历:
function watcher(obj) {
if (typeof obj !== 'object') return
for (const key in obj) {
observer(obj, key)
}
}
将监听写到一个observer方法里,并判断该下面的方法是否是对象,是的话递归调用监听方法,可以监听某对象下的属性
const observer = function (obj, prop) {
if (obj && typeof (obj[prop]) === 'object') {
watcher(obj[prop])
}
var value = obj[prop]
Object.defineProperty(obj, prop, {
get: () => {
return value
},
set: (v) => {
value = v
console.log(`set ${prop} = ${v}`);
}
})
}
运行结果如图所示:
完整代码
const observer = function (obj, prop) {
if (obj && typeof (obj[prop]) === 'object') {
watcher(obj[prop])
}
var value = obj[prop]
Object.defineProperty(obj, prop, {
enumerable: true,
configurable: true,
get: () => {
return value
},
set: (v) => {
if (v !== value) {
value = v
watcher(v)
console.log(`set ${prop} = ${v}`);
}
}
})
}
var data = {
a: 1,
b: {
b1: 2,
b2: {
b31: 4,
b32: 5
}
},
c: 3
}
function watcher(obj) {
if (typeof obj !== 'object') return
for (const key in obj) {
observer(obj, key)
}
}
watcher(data)
data.a = 'a' //set c = a
data.b.b1 = 'b'// set b1 = b
data.b.b2.b31 = 'b3'// set b3 = b3
console.log('data', data);
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!