面试题答案
一键面试Object.defineProperty的作用
Object.defineProperty
用于在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回该对象。它可以精确控制属性的特性,如 value
(属性值)、writable
(是否可写)、enumerable
(是否可枚举)、configurable
(是否可配置),还可以定义 getter
和 setter
函数。
Vue利用Object.defineProperty实现数据劫持与视图更新的原理
- 数据劫持:Vue 在初始化数据时,遍历 data 对象的所有属性,使用
Object.defineProperty
将每个属性转换为getter/setter
形式。这样,当访问或修改这些属性时,会触发getter
或setter
函数。 - 依赖收集:在
getter
中,Vue 会收集依赖,即哪些地方使用了该属性。例如,视图中使用了某个数据属性,那么该视图的渲染函数就成为了这个属性的一个依赖。 - 视图更新:当
setter
被触发,意味着数据发生了变化,Vue 会通知之前收集的依赖,也就是相关的视图更新函数,从而实现视图的更新。
手动使用Object.defineProperty模拟Vue响应式效果示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app"></div>
<script>
const data = {
message: 'Hello, Vue!'
};
const app = document.getElementById('app');
let value = data.message;
Object.defineProperty(data,'message', {
get() {
return value;
},
set(newValue) {
value = newValue;
app.textContent = value;
}
});
// 初始渲染
app.textContent = data.message;
// 模拟数据变化
setTimeout(() => {
data.message = 'Data has changed!';
}, 2000);
</script>
</body>
</html>
在上述代码中,我们创建了一个简单的 data
对象,并使用 Object.defineProperty
为其 message
属性定义了 getter
和 setter
。getter
返回属性值,setter
在属性值变化时更新页面上的文本内容,模拟了 Vue 的响应式效果。