1. 前言
es6
中全新设计了一个叫Proxy
的类型,Proxy
这个词的原意是代理,用在这里表示由它来”代理“某些操作,可以译为”代理器“,可以这样理解:在目标对象之前架设一层"拦截",外界对该对象的访问,都必须先通过这层拦截 。
举个简单的例子
比如茅台酒的代理,有了这个代理,我们就不能直接从茅台公司拿酒,必须通过这个代理
代理说多少钱,就是多少钱,代理说没有就没有
Proxy
代理的是一个对象,这个对象被代理之后,我们就不能直接访问这个对象了,必须通过代理访问。
比如像获取某个属性的值,代理说没有就没有,代理想给你返回啥值就返回啥值
Proxy
就是专门为对象设置访问代理器的,无论是读还是写都要经过代理,通过proxy
就能轻松监视对象的读写过程。
2. 使用
如何使用Proxy
监视对象的读写过程呢?定义一个person
对象,对象当中有一个name
属性和height
属性,然后通过new Proxy
的方式为person
创建一个代理对象,此时proxy
就是为person
对象设置的拦截。
Proxy
的构造函数需要2个参数,一个是需要代理的目标对象,另一个是代理的处理对象,在这个处理对象中可以通过get()
方法监视对象属性的访问,通过set()
方法监视对象设置属性的过程
const person={
name:'zzz',
height:185
}
const proxy=new Proxy(person,{
get(){//监视对象属性的访问
},
set(){//监视对象设置属性的过程
}
})
3. Proxy 实例方法
1. get()方法
get
方法是用于拦截某个属性的读取操作,可以接受三个参数,依次为 目标对象、属性名和 proxy
实例本身 (操作行为所针对的对象),最后一个参数可选。
const proxy=new Proxy(person,{
get(target,propKey){// 目标对象 访问的属性名
console.log(target,propKey); // { } , name
},
set(){
}
})
console.log(proxy.name); // zzz
// 第二个例子
var person = {
name: "张三"
};
var proxy = new Proxy(person, {
get: function(target, propKey) {
if (propKey in target) {
return target[propKey];
} else {
throw new ReferenceError("Prop name \"" + propKey + "\" does not exist.");
}
}
});
proxy.name // "张三"
proxy.age // 抛出一个错误
get()
方法正常的逻辑应该是判断代理目标对象中是否存在访问的属性名,存在就返回对应的值,不存在就返回undefined
或者一个默认值
get(target,propKey){
return propKey in target? target[propKey]:'default'
},
//分别打印存在的属性和不存在的属性
console.log(proxy.name); //zzz
console.log(proxy.age); //default
2. set()方法
set()
方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选。
set(target,propKey,value){
console.log(target,propKey,value);
}
proxy.sex='男'
控制台就会打印出写入的属性和属性值
set()
方法正常的逻辑应该是为代理目标设置指定属性,在设置之前先做一些数据校验,例如属性名为height,那么那么就要判断它的是否是一个数字,不是就抛出错误
set(target,propKey,value){
if(propKey=== 'height'){ //判断属性名是否为height
if(!Number.isInteger(value)){//判断是否为整数
throw new TypeError(`${value} is not an int`)
}
}
target[propKey]=value
}
set
方法的第四个参数receiver
,指的是原始的操作行为所在的那个对象,一般情况下是proxy
实例本身
const handler = {
set: function(obj, prop, value, receiver) {
obj[prop] = receiver;
return true;
}
}
const proxy = new Proxy({}, handler);
proxy.foo = 'bar';
proxy.foo === proxy;
3. apply()方法
apply
方法拦截函数的调用、call
和 apply
操作
接受三个参数,分别是 ==目标对象、目标对象的上下文对象(this
) 和 目标对象的参数数组。
var handler = {
apply(target, ctx, args){
return Reflect.apply(...arguments);
}
};
下面代码中,变量p
是Proxy
的实例,当它作为函数调用时(p()
),就会被apply
方法拦截,返回一个字符串。
var target = function(){ return 'I am the target'};
var handler = {
apply: function(){
return 'i am the proxy';
}
}
var p = new Proxy(target, handler);
console.log(p()); // "i am the proxy"
4. 为什么要存在Proxy?
因为在ES6之前,我们使用Object.defineProperty()
来设置监听器,来监听对象属性的获取和改写。但是如果其中存在其他的一些操作,我们是无法监测到的,所以为了解决这样一个问题,在ES6中增加了Proxy
代理。Proxy
可以帮助我们监听对象中的操作。
两者对比
Object.defineProperty
文章来源:https://www.toymoban.com/news/detail-415660.html
let info = {
name: 'dmc',
age: 20
}
Object.defineProperty(info, 'name', {
get() {
console.log('get--获取info的name值')
return 'dl'
},
set() {
console.log('set--设置info的name值')
}
})
console.log(info.name) // get--获取info的name值 dl
info.name = 'dmc' // set--设置info的name值
Proxy
文章来源地址https://www.toymoban.com/news/detail-415660.html
let info = {
name: 'dmc',
age: 20
}
let infoProxy = new Proxy(info, {
get(target, key) {
console.log('获取对象属性')
return target[key]
},
set(target, key, newValue) {
console.log('设置对象属性')
target[key] = newValue
}
})
到了这里,关于【ES6】阮一峰ES6学习(六) Proxy的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!