面试题答案
一键面试Object.defineProperty 为对象属性添加响应式功能的原理
- 拦截属性访问与修改:
Object.defineProperty
可以定义对象属性的特性,通过设置getter
和setter
函数,当访问或修改对象的属性时,会触发对应的getter
和setter
函数。在 Vue 数据响应式中,getter
用于收集依赖(例如哪些地方使用了这个属性,这些地方就是依赖),setter
用于在属性值变化时通知依赖进行更新。 - 依赖收集:在
getter
中,会将当前正在读取属性的地方(如视图渲染中使用到该属性的地方)作为依赖收集起来。例如,在 Vue 的模板渲染过程中,当读取某个数据对象的属性时,就会把该模板渲染的相关 Watcher(用于观察数据变化并执行相应更新操作的对象)收集到该属性的依赖列表中。 - 触发更新:当属性值通过
setter
被修改时,会遍历该属性收集到的依赖列表,通知所有依赖(Watcher)进行更新操作,从而实现视图等相关部分的更新。
使用方式举例
let data = {
name: '张三'
};
let obj = {};
Object.defineProperty(obj, 'name', {
get() {
console.log('获取 name 属性');
return data.name;
},
set(newValue) {
console.log('设置 name 属性为', newValue);
data.name = newValue;
// 这里可以模拟通知依赖更新的操作
console.log('通知依赖更新');
}
});
console.log(obj.name);
obj.name = '李四';
在上述例子中,通过 Object.defineProperty
为 obj
对象的 name
属性定义了 getter
和 setter
,当获取和设置 name
属性时,会执行相应的 getter
和 setter
函数,并输出对应的日志。这类似 Vue 中数据响应式的基本原理,通过拦截属性操作来实现数据变化的监听与更新。