JavaScript Proxy基本知识梳理( 二 )


get方法可以继承 。

JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , 拦截操作定义在Prototype对象上面 , 所以如果读取obj对象继承的属性时 , 拦截会生效 。
下面的例子使用get拦截 , 实现数组读取负数的索引 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , 数组的位置参数是-1 , 就会输出数组的倒数第一个成员 。
利用 Proxy , 可以将读取属性的操作(get) , 转变为执行某个函数 , 从而实现属性的链式操作 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码设置 Proxy 以后 , 达到了将函数名链式使用的效果 。
下面的例子则是利用get拦截 , 实现一个生成各种 DOM 节点的通用函数dom 。
JavaScript Proxy基本知识梳理

文章插图
 
下面是一个get方法的第三个参数的例子 , 它总是指向原始的读操作所在的那个对象 , 一般情况下就是 Proxy 实例 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , proxy对象的getReceiver属性是由proxy对象提供的 , 所以receiver指向proxy对象 。
JavaScript Proxy基本知识梳理

文章插图
 

JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , d对象本身没有a属性 , 所以读取d.a的时候 , 会去d的原型proxy对象找 。这时 , receiver就指向d , 代表原始的读操作所在的那个对象 。
如果一个属性不可配置(configurable)且不可写(writable) , 则 Proxy 不能修改该属性 , 否则通过 Proxy 对象访问该属性会报错 。
JavaScript Proxy基本知识梳理

文章插图
 
改一下就可以读到属性了
JavaScript Proxy基本知识梳理

文章插图
 
set()
set方法用来拦截某个属性的赋值操作 , 可以接受四个参数 , 依次为目标对象、属性名、属性值和 Proxy 实例本身 , 其中最后一个参数可选 。
假定Person对象有一个age属性 , 该属性应该是一个不大于 200 的整数 , 那么可以使用Proxy保证age的属性值符合要求 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , 由于设置了存值函数set , 任何不符合要求的age属性赋值 , 都会抛出一个错误 , 这是数据验证的一种实现方法 。利用set方法 , 还可以数据绑定 , 即每当对象发生变化时 , 会自动更新 DOM 。
有时 , 我们会在对象上面设置内部属性 , 属性名的第一个字符使用下划线开头 , 表示这些属性不应该被外部使用 。结合get和set方法 , 就可以做到防止这些内部属性被外部读写 。
JavaScript Proxy基本知识梳理

文章插图
【JavaScript Proxy基本知识梳理】 
上面代码中 , 只要读写的属性名的第一个字符是下划线 , 一律抛错 , 从而达到禁止读写内部属性的目的 。
下面是set方法第四个参数的例子
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , set方法的第四个参数receiver , 指的是原始的操作行为所在的那个对象 , 一般情况下是proxy实例本身 , 请看下面的例子 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , 设置myObj.foo属性的值时 , myObj并没有foo属性 , 因此引擎会到myObj的原型链去找foo属性 。myObj的原型对象proxy是一个 Proxy 实例 , 设置它的foo属性会触发set方法 。这时 , 第四个参数receiver就指向原始赋值行为所在的对象myObj 。
注意 , 如果目标对象自身的某个属性 , 不可写且不可配置 , 那么set方法将不起作用 。


推荐阅读