Skip to content

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

这里就要用到 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