【发布时间】:2016-08-12 12:45:08
【问题描述】:
我有一个数组:
const arr = ['a', 'b', 'c']
我使用get 处理程序为该数组创建一个代理,该处理程序将为每个数字n 返回具有n - 1 索引的属性。例如,p[1] 将返回 'a'、p[2] – 'b' 和 p[3] – 'c'。
const p = new Proxy(arr, {
get: (target, property, receiver) => {
const parsed = parseInt(property, 10)
if (!Number.isNaN(parsed)) return target[parsed - 1]
return target[property]
}
})
它似乎工作正常。例如,p[2] 会给出应有的'b'。但是,还有另一个问题。 Array.prototype.indexOf() 不再正常工作。当我通过'a' 或'b' 时它确实有效——它分别返回1 和2,但对于'c' 它返回-1。事实证明indexOf() 也触发了get 处理程序。通过将console.log(property) 添加到get 处理程序,我们得到p.indexOf('c') 的以下输出:
'indexOf'
'length'
'0'
'1'
'2'
似乎indexOf() 内部检查了length 属性,然后将数组从索引0 迭代到length - 1。
如果我知道该属性是直接访问(如p[2])还是内部访问,那么解决这个问题将是微不足道的。然后我总是可以返回target[property] 进行内部访问(因此代理将是无操作的)。
Proxygethandler中如何区分直接访问和内部访问?
我唯一想到的就是抛出一个错误,捕获它并分析它的堆栈。尽管如此,这似乎是一种解决方法,而不是实际的解决方案,所以我想避免它,除非没有其他办法。
【问题讨论】:
-
为什么要采用这些非一的语义?怀念一些基于 1 的语言?
-
@torazaburo 我只是在试验一下,看看是否可以创建一个索引从 1 开始的数组,而不是 0。
-
我认为,但不确定,您必须为
indexOf方法在对象上实现 get 并进行必要的操作。 -
@torazaburo 根据你的建议,我想出了this。你介意我用这个解决方案自行回答问题吗?
标签: javascript ecmascript-6 es6-proxy