Differences Between Typed and Regular Arrays
The most important difference between typed arrays and regular arrays is that typed arrays are not regular arrays. Typed arrays don’t inherit from Array
and Array.isArray()
returns false
when passed a typed array. For example:
let ints = new Int16Array([25, 50]);
console.log(ints instanceof Array); // false
console.log(Array.isArray(ints)); // false
Since the ints
variable is a typed array, it isn’t an instance of Array
and cannot otherwise be identified as an array. This distinction is important because while typed arrays and regular arrays are similar, there are many ways in which typed arrays behave differently.
Behavioral Differences
While regular arrays can grow and shrink as you interact with them, typed arrays always remain the same size. You cannot assign a value to a nonexistent numeric index in a typed array like you can with regular arrays, as typed arrays ignore the operation. Here’s an example:
let ints = new Int16Array([25, 50]);
console.log(ints.length); // 2
console.log(ints[0]); // 25
console.log(ints[1]); // 50
ints[2] = 5;
console.log(ints.length); // 2
console.log(ints[2]); // undefined
Despite assigning 5
to the numeric index 2
in this example, the ints
array does not grow at all. The length
remains the same and the value is thrown away.
Typed arrays also have checks to ensure that only valid data types are used. Zero is used in place of any invalid values. For example:
let ints = new Int16Array(["hi"]);
console.log(ints.length); // 1
console.log(ints[0]); // 0
This code attempts to use the string value "hi"
in an Int16Array
. Of course, strings are invalid data types in typed arrays, so the value is inserted as 0
instead. The length
of the array is still one, and even though the ints[0]
slot exists, it just contains 0
.
All methods that modify values in a typed array enforce the same restriction. For example, if the function passed to map()
returns an invalid value for the typed array, then 0
is used instead:
let ints = new Int16Array([25, 50]),
mapped = ints.map(v => "hi");
console.log(mapped.length); // 2
console.log(mapped[0]); // 0
console.log(mapped[1]); // 0
console.log(mapped instanceof Int16Array); // true
console.log(mapped instanceof Array); // false
Since the string value "hi"
isn’t a 16-bit integer, it’s replaced with 0
in the resulting array. Thanks to this error correction behavior, typed array methods don’t have to worry about throwing errors when invalid data is present, because there will never be invalid data in the array.
Missing Methods
While typed arrays do have many of the same methods as regular arrays, they also lack several array methods. The following methods are not available on typed arrays:
concat()
pop()
push()
shift()
splice()
unshift()
Except for the concat()
method, the methods in this list can change the size of an array. Typed arrays can’t change size, which is why these aren’t available for typed arrays. The concat()
method isn’t available because the result of concatenating two typed arrays (especially if they deal with different data types) would be uncertain, and that would go against the reason for using typed arrays in the first place.
Additional Methods
Finally, typed arrays methods have two methods not present on regular arrays: the set()
and subarray()
methods. These two methods are opposites in that set()
copies another array into an existing typed array, whereas subarray()
extracts part of an existing typed array into a new typed array.
The set()
method accepts an array (either typed or regular) and an optional offset at which to insert the data; if you pass nothing, the offset defaults to zero. The data from the array argument is copied into the destination typed array while ensuring only valid data types are used. Here’s an example:
let ints = new Int16Array(4);
ints.set([25, 50]);
ints.set([75, 100], 2);
console.log(ints.toString()); // 25,50,75,100
This code creates an Int16Array
with four elements. The first call to set()
copies two values to the first and second elements in the array. The second call to set()
uses an offset of 2
to indicate that the values should be placed in the array starting at the third element.
The subarray()
method accepts an optional start and end index (the end index is exclusive, as in the slice()
method) and returns a new typed array. You can also omit both arguments to create a clone of the typed array. For example:
let ints = new Int16Array([25, 50, 75, 100]),
subints1 = ints.subarray(),
subints2 = ints.subarray(2),
subints3 = ints.subarray(1, 3);
console.log(subints1.toString()); // 25,50,75,100
console.log(subints2.toString()); // 75,100
console.log(subints3.toString()); // 50,75
Three typed arrays are created from the original ints
array in this example. The subints1
array is a clone of ints
that contains the same information. Since the subints2
array copies data starting from index 2, it only contains the last two elements of the ints
array (75 and 100). The subints3
array contains only the middle two elements of the ints
array, as subarray()
was called with both a start and an end index.