我有一个数组:
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]
以进行内部访问(因此代理将是空操作)。
如何在 Proxy get
处理程序中区分直接访问和内部访问?
我唯一想到的就是抛出一个错误,捕获它并分析它的堆栈。不过,这似乎是一种解决方法,而不是实际的解决方案,所以我想避免使用它,除非没有其他办法。
最佳答案
It seems that
indexOf()
internally checks thelength
property, and then iterates the array from index0
tolength - 1
.
是的。这是所有内置数组方法的行为。
How to distinguish direct access from internal access in Proxy get handler?
你不能。
It would be trivial to fix that if I knew whether the property is accessed directly or internally.
不,这是错误的方法。如果您期望 forEach
的行为与普通循环不同,那么您的语义就会出现问题。也许您实际上也想拦截 .length
属性?或者环绕索引 0
?在不知道您要解决的问题的情况下,我们几乎无法提出任何有用的建议。
一种极端的措施是编写您自己的所有数组方法版本来处理单索引数组。
关于javascript - 区分代理获取处理程序中的直接访问和内部访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38918316/