ES6基础入门教程(十八)proxy拦截器

Proxy用于拦截对元素的行为。类似于class种的set和get,有多达13种方式。

简单例子:


监听取值行为

let a = new Proxy({},{
    get:(t,p)=>{
        return 35;
    }
})
console.log(a.name);
// 35

如果里面什么都不写,会直接指向该对象。

let b = new Proxy({},{
    // 如果里面什么都不写,等于直接指向该对象
})
b["a"] = "aaa"
console.log(b["a"]);

看到这里,你可能有点懵逼,我再把例子写简单点。

let a = new Proxy({},{
    get:(t,p)=>{
        // t 指a对象本身
        // p 指访问的属性
        if(p="name"){
            console.log(123);
        }
    }
})
//当name被访问的时候 打出123
a.name

然后你此刻必定恍然大悟,卧槽!原来如此。
但是,如果只能实现一个get,那他跟class里面get和set就没区别了呀!
是的,这函数最牛逼的地方在于,他能监听13种操作。。比class里面的get和set牛逼太多了。。

再来一个,假定我们要删除某个属性值:


注意:我们是拦截删除操作,如果你真要删除,你还是得再方法里执行delete..

let obj = {
    num:123,
    brs:22222
};
let arrp = new Proxy(obj,{
    deleteProperty(t,k) {
        console.log(k);
        if(k=="brs"){
            console.log("你无法删除brs");
            return false;
        }
        // 执行删除操作
        delete t[k]
        // 必须返回一个值
        return true;
    }
})
// 正常删除 因为返回true
console.log(arrp.num);
delete arrp.num
console.log(arrp.num);


console.log(arrp.brs);
delete arrp.brs // 如果你尝试删除brs就会报错
console.log(arrp.brs);

这是因为我们设置了阻挡删除 才报得错,这是正常的。

阻挡报错

他总共可以拦截13种操作: 使用的方式都大同小异。

方法 作用
get(target, propKey, receiver) 拦截对象属性的读取,比如proxy.foo和proxy[‘foo’]
set(target, propKey, value, receiver) 拦截对象属性的设置,比如proxy.foo = v或proxy[‘foo’] = v,返回一个布尔值。
has(target, propKey) 拦截propKey in proxy的操作,返回一个布尔值。
deleteProperty(target, propKey) 拦截delete proxy[propKey]的操作,返回一个布尔值。
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)。

Copyright © 2023 | 粤ICP备14006518号-4

Proudly powered by WordPress | Theme: Beast Blog by Crimson Themes.