Syed Muhammad Taha (@smtaha512)
Software Engineer
const arr1 = [1, 2, 3];
const arr2 = ['a', 'b', 'v'];
const arr3 = [{ a: 1 }, { b: 2 }];
const arr1 = [
1,
'a',
{ a: 1 },
true,
() => arr1.length
];
const arr = [1, 2, 3]; // PACKED_SMI_ELEMENTS
const obj = {
a: 1,
b: 2,
c: 3
};
const arr = [
1, 2, 3
];
Objects have properties that map to values.
Arrays have indexes that map to elements.
SMI == SMall Integers
const arr = [
1, 2, 3
]; // PACKED_SMI_ELEMENTS
const arr = [
1, 2, 3
]; // PACKED_SMI_ELEMENTS
arr.push(4.6); //PACKED_DOUBLE_ELEMENTS
// [1, 2, 3, 4.6]
const arr = [
1, 2, 3
]; // PACKED_SMI_ELEMENTS
arr.push(4.6); //PACKED_DOUBLE_ELEMENTS
arr.push('x'); // PACKED_ELEMENTS
// [1, 2, 3, 4.6, 'x']
PACKED_SMI_ELEMENTS
PACKED_DOUBLE_ELEMENTS
PACKED_ELEMENTS
const arr = [
1, 2, 3, 4.6, 'x'
]; // PACKED_ELEMENTS
arr.length
// 5
arr[10] = 120;
// Assigning outside array's bound
const arr = [
1, 2, 3
]; // PACKED_SMI_ELEMENTS
arr.push(4.6); // PACKED_DOUBLE_ELEMENTS
arr.push('x'); // PACKED_ELEMENTS
// [1, 2, 3, 4.6, 'x']
arr[10] = 120; // HOLEY_ELEMENTS
Node JS REPL:
Chrome console:
HOLEY_SMI_ELEMENTS
HOLEY_DOUBLE_ELEMENTS
HOLEY_ELEMENTS
const arr = [1, 2, 3];
arr.push(4.6);
arr.push('x');
// Alert holey array ahead!
arr[10] = 120; // Holes from index = 5 to index = 9
const arr = [1, 2, 3,,10]; // Hole at index = 3
const arr = new Array(3); HOLEY_SMI_ELEMENTS
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
index
value
0
1
1
2
2
3
3
4.6
4
5
6
7
8
9
Bounds check:
Try to access value on array:
Try to access value on prototype chain:
array[8]; // ???
How JavaScript engine will evaluate this?
'x'
8 ≥ 0 && 8 < array.length // true
hasOwnProperty(arr, '8'); // false
hasOwnProperty(Array.prototype, '8'); // false
hasOwnProperty(Object.prototype, '8'); // false
10
120
const arr = [1, 2, 3, 10]; // PACKED_SMI_ELEMENTS
// If you don't know all the values ahead of time
// try using array literal and then push.
const arr = [];
arr.push(someValue);
arr.push(otherValue);
// Don’t do this!
for (let i = 0, item; (item = items[i]) != null; i++) {
doSomething(item);
}
A famous library uses this
Instead, either use:
// Don’t do this!
const array = [3, 2, 1, +0];
// PACKED_SMI_ELEMENTS
array.push(-0);
// PACKED_DOUBLE_ELEMENTS
// Don’t do this!
const array = [3, 2, 1];
// PACKED_SMI_ELEMENTS
array.push(NaN, Infinity);
// PACKED_DOUBLE_ELEMENTS
const elements = document.getElementsByClassName(className);
// Returns HTMLCollection which is an array like object
// Iterating over HTMLCollection using Array prototype
// Not performant as real array
Array.prototype.forEach.call(elements, (val, idx) => {
console.log(idx, val);
})
const elements = document.getElementsByClassName(className);
// Returns HTMLCollection which is an array like object
const elemArr = Array.from(elements);
// Creating array from array like object
elemArr.forEach((val, idx) => {
console.log(idx, val);
})
const each = (array, callback) => {
for (let idx = 0; idx < array.length; ++idx) {
const item = array[idx];
callback(item);
}
};
each(['a', 'b', 'c'], doSomething);
each([1.1, 2.2, 3.3], doSomething);
each([1, 2, 3], doSomething);
Elements kinds in V8
V8 Internals for JavaScript developers
JavaScript Engine Internals for JavaScript Developers
Mathias Bynens(@mathias)