extend Uint8Array then map gives wrong result

Tags:



Why does hex() implementation do not work as expected but the hex2() works fine.

class Bytes extends Uint8Array {
  hex() {
    return this.map(x => x.toString(16).padStart(2, "0")).join('');
  }

  hex2() {
    return [...this].map(x => x.toString(16).padStart(2, "0")).join('');
  }
}

const a = new Bytes([1, 2, 30]);
console.log(a.hex());  // 120
console.log(a.hex2()); // 01021e

Answer

All “legit” .map methods will return an object of the same interface than the one on which it exists.

So on a TypedArray, it will return a TypedArray.

const arr = new Uint8Array();
console.log( arr.map( () => {} ) instanceof Uint8Array );

But a TypedArray can’t hold Strings, only numbers, and for the Uint8Array Typed Array, only integer numbers in the range 0 to 255.
So Uint8Array.map( fnThatReturnsStrings ) will try to cast all the return values to numbers in that range.

"01" => 1
"02" => 2
"1e" => NaN => 0



Source: stackoverflow