defineProperty
为什么vue3中基本不使用defineProperty实现响应式而使用Proxy实现响应式
defineProperty:
- 这种方式只能对修改(set)和读取(get)进行拦截
- 所以当给对象新增一个属性, 或者删除对象的某个属性式,不会经过set和get,导致无法实现响应式
- 并且通过数组下标去修改数组中的数据,也不会实现响应式处理
语法
const Obj = {
name: 'zhansgan'
}
// 创建代理对象
const definePropertyObj = {}
/**
* @param {object} definePropertyObj 创建的代理对象
* @param {string} definePropertyObjName 需要被代理的对象属性名
*/
Object.defineProperty(definePropertyObj, definePropertyObjName, {
get() {
return Obj.name
},
set(value) {
Obj.name = value
}
})
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 创建一个源对象
const user1 = {
name: 'jack'
}
// 创建一个代理对象
const user2 = {}
// 给user2扩展一个属性name,即使用user2给user1代理劫持
Object.defineProperty(user2, 'name', {
// 数据代理
get() {
console.log('读取了');
return user1.name
},
// 数据劫持
set(value) {
// 改数据
user1.name = value
console.log('修改了');
}
})
// 输出:
// user1
// {name: 'jack'}
// user2.name
// index.html:21 读取了
// 'jack'
// user2.name = 'lisi'
// index.html:28 修改了
// 'lisi'
// user1
// {name: 'lisi'}
// user2.age = 10
// 10
// user1
// {name: 'lisi'}
// delete user2.name
// false
// user2
// {age: 10}
// user1
// {name: 'lisi'}
// 注:使用defineProperty进行代理,只能对对象属性的赋值和读取操作进行劫持和代理
// 如对象的属性的新增、删除等都不能进行代理,
// 并且通过数组下标去修改数组中的数据,也不会实现响应式处理
</script>
</body>
</html>