ES2015 Proxy 对比 defineProperty
程序员文章站
2022-03-08 22:18:22
...
如果我们想监视某个对象的读写,我们可以使用ES5提供的defineProperty
方法为对象添加属性,可以捕获到对象属性的读写过程。
defineProperty
应用场景:在vue3.0 以前的版本,就是使用defineProperty
实现了数据响应从而实现双向数据绑定。
因为Proxy比defineProperty强大,vue3.0 中使用的是Proxy
在ES2015中,全新设计了一个叫做Proxy
的类型,专门用来为对象设置访问代理器。
什么是代理呢?
通俗点解释:把代理想象成门卫,无论你是想出去还是想进去放东西都会被监视。
相比于defineProperty
,Proxy
功能更加强大,使用起来也更加方便。
一、Object.defineProperty
的基本使用
ES2015之前 Object.defineProperty
const person = {
name:'luyu',
age:18
}
// ES2015之前 Object.defineProperty
let person2 = Object.assgin({},person)
Object.defineProperty(person,'name',{
set(newVal){
// 不要直接去修改obj1.x,这样会导致死循环(无限递归)
person2.name = newVal;
},
get(){
return person2.name;
}
})
person.name = 20; // set...
二、Proxy
的基本使用
ES2015 之后 Proxy
const person = {
name:'luyu',
age:18
}
// Proxy构造函数的第一个参数是需要代理的模板对象,第二个参数是代理的处理对象
const personProxy= new Proxy(person,{
// 属性的访问
get(target,property){
console.log(target,property)
// 如果对象中有该属性,则返回该属性的值。如果是不存在的属性,则返回默认值
return property in target ? target[property] : 'default'
},
// 属性的设置
set(target,property,value){
console.log(target,property,value)
// 可以先做数据校验
if(!Number.isInteger(value)){
throw new TypeError(`${value} is not an int`)
}
target[property] = value
}
})
console.log(personProxy.name)
personProxy.gender = 'nan'
console.log(person)
三、Proxy
VS defineProperty
相比于defineProperty
,Proxy
有哪些优势?
优点一:defineProperty
只能监视属性的读写,Proxy
能够监视到更多对象操作,例如delete
操作、对象方法的调用等等
const person = {
name:'luyu',
age:18
}
const personProxy = new Proxy(person,{
deleteProperty(target,property){
console.log('delete',property)
delete target[property]
}
})
delete person.name;
console.log(person)// { age: 18 }
除了delete
,还有很多对象操作都能够被监视到:
handler方法 | 触发方式 |
---|---|
get | 读取某个属性 |
set | 写入某个属性 |
has | in 操作符 |
deleteProperty | delete操作符 |
getPrototypeOf | Object.getPrototypeOf() |
setPrototypeOf | Object.setPrototypeOf() |
isExtensible | Object.isExtensible() |
preventExtensions | Object.preventExtensions() |
getOwnPropertyDescriptor | Object.getOwnPropertyDescriptor() |
defineProperty | Object.defineProperty() |
ownKeys | Object.getOwnPropertyNames() 、Object.getOwnPropertySymbols() |
apply | 调用一个函数 |
construct | 用new调用一个函数 |
优点二:Proxy
更好的支持数组对象的监视
如何使用Proxy
对数组进行监视?
// 重写数组的操作方法
const list = []
const listProxy = new Proxy(list,{
set(target,property,value){
target[property] = value;
return true; // 表示设置成功
}
})
listProxy.push(100)
console.log(list) // [100]
优点三:Proxy
是以非侵入的方式监管对象的读写
Proxy
不需要侵入对象:说人话就是,一个已经定义好的对象,我们不需要对它进行操作,就可以监视到他内部成员的读写。
看下面案例对比
Proxy:
const personProxy = new Proxy(person, {
get(target, property) {
return target[property];
},
set(target, property, value) {
return (target[property] = value);
}
});
defineProperty:
Object.defineProperty(person,'name',{
get(){
console.log("name 被访问...");
return person._name;
},
set(newValue){
console.log("name 被设置 ...");
person._name = newValue;
}
})
person.name = 'luyu'// name 被设置 ...
console.log(person.name) // name 被访问 ... luyu
上一篇: php怎么实现每天自动运行
下一篇: cpanel如何修改php.ini
推荐阅读
-
ES6 Proxy 与 Object.defineProperty 的优劣对比?
-
Proxy 与 Object.defineProperty对比
-
ES6之Object.defineProperty 和 Proxy 区别
-
ES2015箭头函数与普通函数对比理解
-
Object.defineProperty与proxy进行对比
-
ES2015 Proxy代理对象与Reflect反射对象
-
Proxy 与Object.defineProperty介绍与对比
-
使用 Object.defineProperty (vue2)和 Proxy(vue3)实现Vue双向数据绑定
-
分别使用 Object.defineProperty 和 proxy 实现简单的数据双向绑定
-
Proxy 和 Object.defineProperty 区别以及常见使用场景