一、分析
两个关键词,Proxy
和Reflect
1. Proxy
使用Proxy
代理一个对象时,会返回一个代理值。读取代理值的属性时会触发get
函数,修改代理值的属性时会触发set
函数。
例子如下:
- 创建了一个响应式对象
person
- 读取
person.name
时,触发 get 函数,控制台打印读取->name
- 修改
person.name
时,触发 set 函数,控制台打印修改->name->李四
const person = new Proxy(
{ name: '张三' },
{
get(target, prop) {
console.log(`读取->${prop}`)
return target[prop]
},
set(target, prop, value) {
console.log(`修改->${prop}->${value}`)
target[prop] = value
},
}
)
person.name // 读取
person.name = '李四' // 修改
// 控制台打印
// 读取->name
// 修改->name->李四
2. Reflect
Reflect
的作用是调用对象的基本操作(内部方法),详情参考 MDN
const obj = { a: 1 }
obj.a // 1
Reflect.get(obj, 'a') //1
obj.a = 2 //2
Reflect.set(obj, 'a', 2) //2
从结果上看,执行 obj.a
和 Reflect.get(obj, 'a')
一样;执行obj.a = 2
和 Reflect.set(obj, 'a',2)
一样。那他们的区别是什么?
区别一
执行 obj.a 实际上等于执行
------------------------------------------------------------------
xxx
xxx
Reflect.get(obj, 'a')
xxx
xxx
------------------------------------------------------------------
也就是说 Reflect.get(obj, 'a') 是执行 obj.a 中的某一个步骤,
同理 Reflect.set(obj, 'a',2) 是执行 obj.a = 2 中的某一个步骤
如果我们不需要其他步骤,那么就可以使用 Reflect
来跳过这些步骤
区别二
Reflect.get(target, propertyKey[, receiver])
Reflect.set(target, propertyKey, value[, receiver])
可以接收一个receiver
参数,用来改变this的指向
const obj = {
a: 1,
b: 2,
get c() {
return this.a + this.b
},
}
console.log(obj.c) // 3
console.log(Reflect.get(obj, 'c')) //3
console.log(Reflect.get(obj, 'c', { a: 3, b: 4 })) //7
二、实现
/**
* 创建一个响应式对象
* @param {Object} obj
*/
function reactive(obj) {
const proxy = new Proxy(obj, {
get(target, prop) {
console.log(`读取->${prop}`)
return Reflect.get(target, prop, proxy) // 是调用 Reflect 将对象中的 this 指向代理
},
set(target, prop, value) {
console.log(`修改->${prop}->${value}`)
Reflect.set(target, prop, value, proxy)
},
})
return proxy
}
// 使用示例
const person = reactive({
name: '张三',
age: 18,
get info() {
return this.name + '-' + this.age
},
})
console.log(person.name)
console.log(person.age)
console.log(person.info)
person.name = '李四'
person.age = 20
console.log(person.name)
console.log(person.age)
console.log(person.info)
控制台打印
读取->name
张三
读取->age
18
读取->info
读取->name
读取->age
张三-18
修改->name->李四
修改->age->20
读取->name
李四
读取->age
20
读取->info
读取->name
读取->age
李四-20
三、结合html
原文链接:https://juejin.cn/post/7352079398071943231 作者:_Xyuan