gpt4 book ai didi

Javascript - TypedArray.prototype.set 的奇怪行为

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:53:58 24 4
gpt4 key购买 nike

当我注意到一些奇怪的事情时,我正在研究 JavaScript 的 TypedArrays。我认为 TypedArray.prototype.set 方法的实现会简单地增量复制值。因此,我尝试欺骗系统以查看此行为:

var ar = new Uint8Array([1,2,3,4,5,6,7,8]);ar.set(ar.subarray(0,6),2);

我认为,如果它从 0 处的 ar 开始复制,但覆盖 2 处的值,子数组将被操作,因此一旦到达索引 2 就开始循环。因此,我自然会期望 Uint8Array(8) [1,2,1,2,1,2,1,2] 的输出,但是,在检查 ar 时:

> arUint8Array(8) [1,2,1,2,3,4,5,6]

所以,我想它可能是向后复制的?

var ar = new Uint8Array([1,2,3,4,5,6,7,8]);ar.set(ar.subarray(2),0);> arUint8Array(8) [3,4,5,6,7,8,7,8]

没有。对此感到不安,然后我决定使用代理来检查内部行为:

ar = new Uint8Array([1,2,3,4,5,6,7,8]);pxy = new Proxy(ar.subarray(0,6),{    get: (o,p)=>{console.log("get",o,p,o[p]); return o[p]}});> ar.set(pxy,2);get Uint32Array(6) [1, 2, 3, 4, 5, 6] length 6get Uint32Array(6) [1, 2, 3, 4, 5, 6] 0 1get Uint32Array(6) [1, 2, 1, 4, 5, 6] 1 2get Uint32Array(6) [1, 2, 1, 2, 5, 6] 2 1get Uint32Array(6) [1, 2, 1, 2, 1, 6] 3 2get Uint32Array(6) [1, 2, 1, 2, 1, 2] 4 1get Uint32Array(6) [1, 2, 1, 2, 1, 2] 5 2> arUint8Array(8) [1,2,1,2,1,2,1,2]

而且,唉,一旦我试图观察它,它就会偷偷溜走,并按照我最初的预期行事!

我已经在 Chrome 和 Firefox 中运行了这个测试,两者都给出了相同的结果。我还在 MS Edge 中对其进行了测试,它似乎也给出了相同的结果(尽管有时它会随机崩溃 JS 运行时 - 可能与代理有关)。

这是错误还是特定行为?什么时候(和/或为什么)我应该期待这种行为?还是我应该完全避免将 TypedArray 设置为其自己的子数组?

最佳答案

这是指定的行为。您可以信赖这一点。

当您将类型化数组设置到它自己的子数组时(即,当两个类型化数组都是同一缓冲区的 View 时),源区域在写入之前被显式克隆进入目的地。这是为了防止 [1,2,1,2,1,2,1,2] 结果 - 它通常是不需要的和意外的。

使用代理检查内部行为在这里失败了,因为使用代理改变了行为。我上面所说的仅当您将另一个类型化数组传递给 set 方法时适用 - 但 Proxy(即使具有类型化数组目标)也不算作类型化数组。它像从任何其他类似数组的对象一样回退到正常复制,它确实像您最初描述的那样工作。

关于Javascript - TypedArray.prototype.set 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51308432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com