Appearance
02. foo[1][2][3]
如何定义 foo
,使得以下等式成立?
js
foo[1][2][3] == 6
foo[100][200] == 300
foo[100][200][300] == 600
foo[10][20] == 30
1
2
3
4
2
3
4
这里就要用到 Proxy
(代理)了,如果你不熟悉代理,请先阅读 MDN 文档之后再来结合代码中的注释阅读代码,代码本身不复杂,关键是一些底层原理。你也可以直接看我的掘金文章:add(1)(2)(3)你会写了,那么add[1][2][3]呢?
js
// 被代理的目标对象,有一个属性 sum,用来进行累加
const target = { sum: 0 }
// handler 参数,定义一个 get 捕获器
const handler = {
get(trapTarget, property, receiver) {
// 原表达式中的 == 操作会触发代理的 toPrimitive 隐式转换 ...(1)
// 在代理对象中具体以 Symbol.toPrimitive 的形式存在
if (property === Symbol.toPrimitive) {
// 最后一次触发的是==操作,则返回累加的结果
// 这里需要暂时储存结果,因为要清空 0,以进行下一次表达式计算 ...(2)
let temp = trapTarget.sum
// 清空 sum 属性
trapTarget.sum = 0
// Symbol.toPrimitive 是一个对象内部的【函数属性】...(3)
// 内部需要执行该函数,因此套了一个箭头函数,执行结果是返回累积和
return () => temp
}
// 访问的属性为数字,会被转为字符串,因此要转回数字 ...(4)
trapTarget.sum += Number(property)
// 返回代理本身,以进行下一次访问,达到 add[1][2][3] 连续访问的目的
return receiver
}
}
const add = new Proxy(target, handler)
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25