南辞派

导航

Proxy了解

Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种'元编程',即对编程语言进行编程.

Proxy可以理解成,在目标对象之前假设一层拦截,外界对该对象的访问,都必须先通过这层拦截,一次提供了一种机制,可以对外界的访问进行过滤和改写.Proxy这个词的原意是代理,用在这里表示由它来'代理'某些操作,可以译为'代理器'.

Proxy对象的常用解构组成:

let proxy=new Proxy(target,handler);
>>target:表示需要被代理的目标对象

>>handler:也是一个对象,对象中分别存在两个属性方法:get和set

>>>> get属性方法用于拦截某个属性的读取操作

>>>> set属性方法用于拦截某个属性的设置操作

handler:{
	get(target,_prop,_proxy){
		// target:表示被代理的对象
		// _prop:表示读取的被代理对象的属性
		// _proxy:可选参数,表示Proxy实例对象
	},
	set(target,_prop,_value,_proxy){
		// target:表示被代理的对象
		// _prop:表示设置的被代理的对象的属性
		// _value:表示设置的值
		// _proxy:可选参数,表示Proxy实例对象
	}
}

注意:

要使得Proxy起作用,必须针对Proxy实例对象进行操作,而不是针对目标对象(被代理对象)进行操作。

简单案例:

/** 对象代理 **/

// 创建一个对象person(被代理的对象)
const person={
	name:'XiaoMei',
	age:29,
	sex:'女',
	address:"江苏南京"
}

// 创建一个Proxy实例对象代理person
const proxyPerson=new Proxy(person,{
	get(target,_prop){
        // 设置需要获取年龄时,一律返回18
		return _prop==='age'?18:target[_props];
	},
    set(target,_prop,_value){
        // 当设置address属性,且属性值中含有 '北京' 字符时,该属性保持不变
        if(_prop==='address'&&_value.indexOf('北京')!=-1){
            return;
        }
        return (target[_prop] = _value);
    }
})

proxyPerson.address='福建厦门';
console.log(person); // {name:'XiaoMei',age:30,sex:'女',address:'福建厦门'};

proxyperson.address='中国北京';
console.log(person); // {name:'XiaoMei',age:30,sex:'女',address:'江苏南京'};

console.log(proxyPerson.age); // 18
console.log(proxyPerson.name); // XiaoMei

/** 数组代理 **/

const list=['Hello',true,2020];

const listProxy=new Proxy(list,{
	get(target,_prop){
		return _prop>target.length-1?'暂无数据':target[_prop];
	},
    set(target,_prop,_value){
        if(target.includes(_value)){
            console.log('数据已经存在');
            return;
        }
        console.log('插入成功')
        return target.push(_value);
    }
})

console.log(listProxy[3]); // 暂无数据
console.log(listProxy[2]); // 2020

listProxy[listProXy.length]=1; // 插入成功

listProxy[listProxy.length]='Hello';

Proxy支持拦截的操作

get(target, _prop, _proxy):

拦截被代理对象属性的读取,比如proxy.fooproxy['foo']

set(target, _prop, _value,_proxy)

拦截对象属性的设置,比如proxy.foo = vproxy['foo'] = v,返回一个布尔值。

has(target, _prop)

拦截 _prop in proxy`的操作(即拦截判断指定属性是否属于指定对象的操作),返回一个布尔值。

deleteProperty(target, _prop)

拦截delete proxy[_prop]的操作,返回一个布尔值。

ownKeys(target)

拦截Object.getOwnPropertyNames(proxy)Object.getOwnPropertySymbols(proxy)Object.keys(proxy)for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。

getOwnPropertyDescriptor(target, _prop)

拦截Object.getOwnPropertyDescriptor(proxy, _prop),返回属性的描述对象。

defineProperty(target, _prop, propDesc):

拦截Object.defineProperty(proxy, _prop, propDesc)Object.defineProperties(proxy, propDescs),返回一个布尔值。

preventExtensions(target)

拦截Object.preventExtensions(proxy),返回一个布尔值。

getPrototypeOf(target):

拦截Object.getPrototypeOf(proxy),返回一个对象。

isExtensible(target):

拦截Object.isExtensible(proxy),返回一个布尔值。

setPrototypeOf(target, proto):

拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。

apply(target, object, args)

拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)proxy.call(object, ...args)proxy.apply(...)

construct(target, args):

拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)

posted on 2020-10-26 12:07  HuaiJinCi  阅读(91)  评论(0编辑  收藏  举报