美文网首页日常刻书
一些常用的代理陷阱函数(三)

一些常用的代理陷阱函数(三)

作者: F_wind | 来源:发表于2021-02-16 08:01 被阅读0次

    《深入理解ES6》阅读随笔

    属性描述符陷阱

    在 JavaScript 中,对象有 defineProperty 和 getOwnPropertyDescriptor 方法,分别用于自定义对象属性和获取对象属性信息;这两个方法在代理陷阱中也有相应的实现,并且接收参数也保持一致:

    • defineProperty 接收三个参数
    1. trapTargat 目标对象;
    2. key 属性描述符键;
    3. value 属性描述符值;
    • getOwnPropertyDescriptor 接收三个参数
    1. trapTargat 目标对象;
    2. key 属性描述符键;
    默认用法

    在默认情况下,代理陷阱转发了对象的 defineProperty 和 getOwnPropertyDescriptor 方法,功能看起来是没有变化的:

    const targat = {}
    
    const proxy = new Proxy(targat, {
        defineProperty(trapTargat, key, descriptor) {
            return Reflect.defineProperty(trapTargat, key, descriptor);
        },
        getOwnPropertyDescriptor(trapTargat, key) {
            return Reflect.getOwnPropertyDescriptor(trapTargat, key);
        }
    })
    
    Object.defineProperty(proxy, 'name', { value: 100 })
    console.log(Object.getOwnPropertyDescriptor(proxy, 'name')) // { value: 100, writable: false, enumerable: false, configurable: false }
    console.log(Object.getOwnPropertyDescriptor(targat,'name')) // { value: 100, writable: false, enumerable: false, configurable: false }
    
    给 getOwnPropertyDescriptor 添加使用限制

    可以在代理陷阱中,通过判断键的类型,来筛选一些满足条件的情况,然后拒绝其获取属性描述的权利:

    const targat = {}
    
    const proxy = new Proxy(targat, {
        defineProperty(trapTargat, key, descriptor) {
            if (descriptor)
                return Reflect.defineProperty(trapTargat, key, descriptor);
        },
        getOwnPropertyDescriptor(trapTargat, key) {
              // 拒绝获取字符串类型键的描述
            if (typeof key === 'string') {
                return false
            }
            return Reflect.getOwnPropertyDescriptor(trapTargat, key);
        }
    })
    Object.defineProperty(proxy, 'name', { value: 100 })
    console.log(Object.getOwnPropertyDescriptor(proxy, 'name')) // err
    
    描述符对象限制

    在使用 Object.defineProperty 定义属性时,第三个属性描述参数只允许接收含有 enumerable、writable、configurable 、value、get 和 set 属性的标准对象,否则无法执行成功,这个地方 Reflect.defineProProperty 也保持一致。
    但是在使用 Object.getOwnPropertyDescriptor 时,存在一些差异,当在代理中返回非标准对象时,会报异常:

    const proxy = new Proxy(targat, {
        getOwnPropertyDescriptor(trapTargat, key) {
            return {
                value1:200
            }
        }
    })
    
    console.log(Object.getOwnPropertyDescriptor(targat, 'name')) // err
    
    差异性
    • defineProperty
      Object.defineProperty 在执行成功后,会将第一个参数目标对象作为返回结果,而 Reflect.defineProperty 在执行成功后会返回 true,否则返回 false:
    const targat = {value:1}
    
    console.log(Object.defineProperty(targat, 'name', { value: 100 }))  // {value:1}
    console.log(Reflect.defineProperty(targat, 'name', { value: 100 }))  // true
    
    • getOwnPropertyDescriptor
      Object. getOwnPropertyDescriptor 在第一个接收参数位置收到一个非对象类值时,会对其进行强制转换,因此返回一个 undefined 结果,而 Reflect.defineProperty 则会直接报异常:
    console.log(Object.getOwnPropertyDescriptor(1, 'name')) // undefined
    console.log(Reflect.getOwnPropertyDescriptor(1, 'name')) // err
    

    相关文章

      网友评论

        本文标题:一些常用的代理陷阱函数(三)

        本文链接:https://www.haomeiwen.com/subject/ypcvxltx.html