Proxy/Reflect
this 和 receiver
Proxy 的 get() 里的 this 和 receiver
Proxy 的get()
方法里的receiver
总是指向原始的读操作所在的那个对象。
常规情况下,receiver
即为 Proxy 实例。
const origin = {
a: 'a'
};
const proxy = new Proxy(origin, {
get(target, key, receiver) {
// 读操作是在 proxy 对象上进行的,因此 receiver === proxy
console.log('receiver === proxy -->', receiver === proxy);
return Reflect.get(target, key, receiver);
}
});
proxy.a;
// 结果
// receiver === proxy --> true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
而当 Proxy 实例位于读操作所在对象的原型链上时,Proxy 的get()
方法里的receiver
就会指向读操作所在的对象。
const origin = {
a: 'a'
};
const proxy = new Proxy(origin, {
get(target, key, receiver) {
// 读操作是在 child 对象上进行的,因此 receiver === child
console.log('receiver === proxy -->', receiver === proxy);
console.log('receiver === child -->', receiver === child);
return Reflect.get(target, key, receiver);
}
});
const child = Object.create(proxy);
child.a;
// 结果
// receiver === proxy --> false
// receiver === child --> true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Proxy 的 set() 里的 receiver
类似于get()
,Proxy 的set()
里的receiver
指的是原始的写操作所在的那个对象。
const origin = {
a: 'a'
};
const proxy = new Proxy(origin, {
set(target, key, value, receiver) {
// 写操作是在 proxy 对象上进行的,因此 receiver === proxy
console.log('receiver === proxy -->', receiver === proxy);
return Reflect.set(target, key, value, receiver);
}
});
proxy.a = 'b';
// 结果
// receiver === proxy --> true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const origin = {
a: 'a'
};
const proxy = new Proxy(origin, {
set(target, key, value, receiver) {
// 写操作是在 child 对象上进行的,因此 receiver === child
console.log('receiver === proxy -->', receiver === proxy);
console.log('receiver === child -->', receiver === child);
return Reflect.set(target, key, value, receiver);
}
});
const child = Object.create(proxy);
child.a = 'b';
// 结果
// receiver === proxy --> false
// receiver === child --> true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Proxy 的 get()/set() 里的 this
无论proxy
实例是否位于读/写操作所在对象的原型链上,Proxy 的get
/set
方法里的this
,都指向定义get
/set
时所在的那个对象。
const origin = {
a: 'a'
};
const handler = {
get(target, key, receiver) {
console.log('this === handler -->', this === handler);
return Reflect.get(target, key, receiver);
}
}
const proxy = new Proxy(origin, handler);
proxy.a;
// 结果
// this === handler --> true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
set
同理。在实际应用中,基本上不会在get
/set
里使用this
。
Proxy 的 get() 返回的函数内的 this
Proxy 里get()
方法返回的若是函数的话,则该函数会自动绑定this
为proxy
实例,无论这个函数来自于哪里。
const origin = {
fn() {
console.log('origin.fn:');
console.log('this === proxy -->', this === proxy);
},
fn1() {
console.log('origin.fn1:');
console.log('this === proxy -->', this === proxy);
}
}
const instrumentation = {
fn() {
console.log('instrumentation.fn: ');
console.log('this === proxy -->', this === proxy);
}
}
const globalFn2 = function() {
console.log('globalFn2: ');
console.log('this === proxy -->', this === proxy);
}
const proxy = new Proxy(origin, {
get(target, key, receiver) {
if (key === 'fn') {
// 即使不传入 receiver,结果仍一样
return Reflect.get(instrumentation, key, receiver)
}
if (key === 'fn1') {
// 即使不传入 receiver,结果仍一样
return Reflect.get(target, key, receiver);
}
if (key === 'fn2') {
return globalFn2;
}
}
})
proxy.fn();
// 结果
// instrumentation.fn:
// this === proxy --> true
proxy.fn1();
// 结果
// origin.fn1:
// this === proxy --> true
proxy.fn2();
// 结果
// globalFn2:
// this === proxy --> true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Reflect.get() 里的 this 和 receiver
当origin
有getter
函数时,调用Reflect.get()
不传入第三个参数receiver
,则origin
里的getter
函数里的this
指向origin
。
const origin = {
a: 'a',
b: 'b',
get c() {
console.log('this === receiver -->', this === receiver);
console.log('this === origin -->', this === origin);
return this.a + this.b;
}
}
const receiver = {
a: 1,
b: 2
}
console.log(Reflect.get(origin, 'c'))
// 结果
// this === receiver --> false
// this === origin --> true
// ab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
当origin
有getter
函数时,调用Reflect.get()
若传入第三个参数receiver
,则origin
里的getter
函数里的this
指向receiver
。
const origin = {
a: 'a',
b: 'b',
get c() {
console.log('this === receiver -->', this === receiver);
console.log('this === origin -->', this === origin);
return this.a + this.b;
}
}
const receiver = {
a: 1,
b: 2
}
console.log(Reflect.get(origin, 'c', receiver))
// 结果
// this === receiver --> true
// this === origin --> false
// 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Reflect.set() 里的 this 和 receiver
同理,当origin
有setter
函数时,调用Reflect.set()
若不传入第四个参数receiver
,则origin
里的setter
函数里的this
指向origin
;如传入第四个参数receiver
,则origin
里的setter
函数里的this
指向receiver
。
const origin = {
a: 'a',
b: 'b',
set c(value) {
console.log('this === receiver -->', this === receiver);
console.log('this === origin -->', this === origin);
}
}
const receiver = {
a: 1,
b: 2
}
Reflect.set(origin, 'c', 'c')
// 结果
// this === receiver --> false
// this === origin --> true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const origin = {
a: 'a',
b: 'b',
set c(value) {
console.log('this === receiver -->', this === receiver);
console.log('this === origin -->', this === origin);
}
}
const receiver = {
a: 1,
b: 2
}
Reflect.set(origin, 'c', 'c', receiver)
// 结果
// this === receiver --> true
// this === origin --> false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19