@@ -119,7 +119,7 @@ fproxy.foo; // 'Hello, foo'
119
119
120
120
** (1)get(target, propKey, receiver)**
121
121
122
- 拦截对象属性的读取,比如` proxy.foo ` 和` proxy['foo'] ` ,返回类型不限。最后一个参数receiver可选,当target对象设置了propKey属性的get函数时,receiver对象会绑定get函数的this对象 。
122
+ 拦截对象属性的读取,比如` proxy.foo ` 和` proxy['foo'] ` ,返回类型不限。最后一个参数 ` receiver ` 可选,当 ` target ` 对象设置了 ` propKey ` 属性的 ` get ` 函数时, ` receiver ` 对象会绑定 ` get ` 函数的 ` this ` 对象 。
123
123
124
124
** (2)set(target, propKey, value, receiver)**
125
125
@@ -177,15 +177,15 @@ fproxy.foo; // 'Hello, foo'
177
177
178
178
** (15)construct(target, args, proxy)**
179
179
180
- 拦截Proxy实例作为构造函数调用的操作,比如new proxy(...args)。
180
+ 拦截Proxy实例作为构造函数调用的操作,比如 ` new proxy(...args)` 。
181
181
182
182
## Proxy实例的方法
183
183
184
- 下面是其中几个重要拦截方法的详细介绍 。
184
+ 下面是上面这些拦截方法的详细介绍 。
185
185
186
186
### get()
187
187
188
- get方法用于拦截某个属性的读取操作 。上文已经有一个例子,下面是另一个拦截读取操作的例子。
188
+ ` get ` 方法用于拦截某个属性的读取操作 。上文已经有一个例子,下面是另一个拦截读取操作的例子。
189
189
190
190
``` javascript
191
191
var person = {
@@ -206,9 +206,50 @@ proxy.name // "张三"
206
206
proxy .age // 抛出一个错误
207
207
```
208
208
209
- 上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回undefined 。
209
+ 上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回 ` undefined ` 。
210
210
211
- 利用proxy,可以将读取属性的操作(get),转变为执行某个函数。
211
+ ` get ` 方法可以继承。
212
+
213
+ ``` javascript
214
+ let proto = new Proxy ({}, {
215
+ get (target , propertyKey , receiver ) {
216
+ console .log (' GET ' + propertyKey);
217
+ return target[propertyKey];
218
+ }
219
+ });
220
+
221
+ let obj = Object .create (proto);
222
+ obj .xxx // "GET xxx"
223
+ ```
224
+
225
+ 上面代码中,拦截操作定义在Prototype对象上面,所以如果读取` obj ` 对象继承的属性时,拦截会生效。
226
+
227
+ 下面的例子使用` get ` 拦截,实现数组读取负数的索引。
228
+
229
+ ``` javascript
230
+ function createArray (... elements ) {
231
+ let handler = {
232
+ get (target , propKey , receiver ) {
233
+ let index = Number (propKey);
234
+ if (index < 0 ) {
235
+ propKey = String (target .length + index);
236
+ }
237
+ return Reflect .get (target, propKey, receiver);
238
+ }
239
+ };
240
+
241
+ let target = [];
242
+ target .push (... elements);
243
+ return new Proxy (target, handler);
244
+ }
245
+
246
+ let arr = createArray (' a' , ' b' , ' c' );
247
+ arr[- 1 ] // c
248
+ ```
249
+
250
+ 上面代码中,数组的位置参数是` -1 ` ,就会输出数组的倒数最后一个成员。
251
+
252
+ 利用proxy,可以将读取属性的操作(` get ` ),转变为执行某个函数,从而实现属性的链式操作。
212
253
213
254
``` javascript
214
255
var pipe = (function () {
@@ -229,11 +270,11 @@ var pipe = (function () {
229
270
}
230
271
}());
231
272
232
- var double = function ( n ) { return n * 2 } ;
233
- var pow = function ( n ) { return n * n } ;
234
- var reverseInt = function ( n ) { return n .toString ().split (' ' ).reverse ().join (' ' )| 0 } ;
273
+ var double = n => n * 2 ;
274
+ var pow = n => n * n ;
275
+ var reverseInt = n => n .toString ().split (' ' ).reverse ().join (' ' ) | 0 ;
235
276
236
- pipe (3 ) . double . pow . reverseInt . get
277
+ pipe (3 ). double . pow . reverseInt . get
237
278
// 63
238
279
```
239
280
@@ -756,17 +797,27 @@ Proxy(target, {
756
797
757
798
上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用` Reflect.set ` 方法将值赋值给对象的属性,然后再部署额外的功能。
758
799
759
- 下面是get方法的例子 。
800
+ 下面是另一个例子 。
760
801
761
802
``` javascript
762
803
var loggedObj = new Proxy (obj, {
763
- get : function (target , name ) {
764
- console .log (" get" , target, name);
804
+ get (target , name ) {
805
+ console .log (' get' , target, name);
765
806
return Reflect .get (target, name);
807
+ },
808
+ deleteProperty (target , name ) {
809
+ console .log (' delete' + name);
810
+ return Reflect .deleteProperty (target, name);
811
+ },
812
+ has (target , name ) {
813
+ console .log (' has' + name);
814
+ return Reflect .has (target, name);
766
815
}
767
816
});
768
817
```
769
818
819
+ 上面代码中,每一个Proxy对象的拦截操作(` get ` 、` delete ` 、` has ` ),内部都调用对应的Reflect方法,保证原生行为能够正常执行。添加的工作,就是将每一个操作输出一行日志。
820
+
770
821
## Reflect对象的方法
771
822
772
823
Reflect对象的方法清单如下。
0 commit comments