I was playing around with JavaScript's TypedArrays when I noticed something a bit strange. I figured the implementation of the TypedArray.prototype.set method would simply copy values incrementally. Thus, I tried tricking the system to see this behavior:
var ar = new Uint8Array([1,2,3,4,5,6,7,8]); ar.set(ar.subarray(0,6),2);
I perceived that, if it started copying from ar
at 0, but overwrote values at 2, the subarray would be manipulated, and thus start looping once it reached index 2. Therefore, I would naturally expect an output of Uint8Array(8) [1,2,1,2,1,2,1,2]
, but, when inspecting ar
:
> ar Uint8Array(8) [1,2,1,2,3,4,5,6]
So, I figured perhaps it copied backwards?
var ar = new Uint8Array([1,2,3,4,5,6,7,8]); ar.set(ar.subarray(2),0); > ar Uint8Array(8) [3,4,5,6,7,8,7,8]
Nope. Rather unsettled by this, I then decided to use a Proxy to inspect internal behavior:
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 6 get Uint32Array(6) [1, 2, 3, 4, 5, 6] 0 1 get Uint32Array(6) [1, 2, 1, 4, 5, 6] 1 2 get Uint32Array(6) [1, 2, 1, 2, 5, 6] 2 1 get Uint32Array(6) [1, 2, 1, 2, 1, 6] 3 2 get Uint32Array(6) [1, 2, 1, 2, 1, 2] 4 1 get Uint32Array(6) [1, 2, 1, 2, 1, 2] 5 2 > ar Uint8Array(8) [1,2,1,2,1,2,1,2]
And, alas, as soon as I attempt to observe it, it sneaks away and acts as I first anticipated!
I've run this test in Chrome and Firefox, and both give the same results. I also tested it in MS Edge, and it also seems to give the same results (though at times it would randomly crash the JS runtime - perhaps it was related to the proxy).
Is this a bug or is this specified behavior? When (and/or why) should I expect this behavior? Or should I just altogether evade setting a TypedArray to its own subarray?