日常刻书

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

2021-02-16  本文已影响0人  F_wind

《深入理解ES6》阅读随笔

属性描述符陷阱

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

  1. trapTargat 目标对象;
  2. key 属性描述符键;
  3. value 属性描述符值;
  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
差异性
const targat = {value:1}

console.log(Object.defineProperty(targat, 'name', { value: 100 }))  // {value:1}
console.log(Reflect.defineProperty(targat, 'name', { value: 100 }))  // true
console.log(Object.getOwnPropertyDescriptor(1, 'name')) // undefined
console.log(Reflect.getOwnPropertyDescriptor(1, 'name')) // err
上一篇下一篇

猜你喜欢

热点阅读