注册 登录

清河洛

ES6的代理对象Proxy

qingheluo2023-09-16清河洛712
Proxy用于修改某些对象操作的默认行为,可以理解成在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,可以对外界的访问进行过滤和改写Proxy(target,handlers):创建代理对象target 要拦截的目标对象 handlers 处理器对象,用来定制拦截行为Proxy支持的拦截操作一共13种以下函数中propKey为键名,receiver为代理对象本身,可以省略该参数get(target, propKey, receiver):拦截对象属性的读取set(target, propKey, value, receiver):拦截对象属性的设置,返回一...

Proxy用于修改某些对象操作的默认行为,可以理解成在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,可以对外界的访问进行过滤和改写

Proxy(target,handlers):创建代理对象

target    要拦截的目标对象
handlers  处理器对象,用来定制拦截行为

Proxy支持的拦截操作一共13种

以下函数中propKey为键名,receiver为代理对象本身,可以省略该参数

get(target, propKey, receiver):拦截对象属性的读取

set(target, propKey, value, receiver):拦截对象属性的设置,返回一个布尔值

has(target, propKey):拦截key in proxy的操作,返回一个布尔值

deleteProperty(target, propKey):拦截delete操作,返回一个布尔值。

ownKeys(target):

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

getOwnPropertyDescriptor(target, propKey)

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

defineProperty(target, propKey, propDesc)

    拦截
    Object.defineProperty(proxy, propKey, 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)

应用示例:数组支持负数索引

let arr = [0,1,2,3,4,5,6];
let proxy = new Proxy(
    arr,
    {
        get:function(target,key){
            let index = +key;
                // 将key转换为数字
            if (index>0){
                return target[index];
            }else{
                return target[target.length + index];
            }
        }
    }
);

Proxy.revocable(target, handler):用来创建一个可取消的Proxy

let {proxy, revo} = Proxy.revocable({}, {});

proxy.foo = 123;
proxy.foo // 123

revo();
proxy.foo // TypeError: Revoked

Proxy.revocable()的一个使用场景是,目标对象不允许直接访问,必须通过代理访问,一旦访问结束,就收回代理权,不允许再次访问

Proxy中的this问题

一旦proxy代理target,target.func()内部的this就是指向proxy,而不是target

所以,虽然proxy没有做任何拦截,target.func()和proxy.func()返回不一样的结果



网址导航