0

Examples of sparse array:

// first
let array = new Array(3);
// second 
let array = [1,,3];
// third
let array = [1, 2, 3]; // not sparse
delete array[1]; // now it is
// fourth
let array = [1,2 3]; // not sparse
array[1000] = 'foo'; // now it is

Does setting an existing value to undefined or null also make it sparse?


I have an array of objects and I need to express empty slot somehow without making it into sparse because it's then flagged as sparse in modern browser engines and lookup speed is about the same as object key lookup - it needs to walk the prototype chain (a lot slower than index lookup).

5
  • 1
    So you didn't try to see for yourself? No, null and undefined are values in JavaScript, so assigning those values to entries does not make the array sparse. Commented Dec 11, 2019 at 6:13
  • No. It will simply set the value of that element to undefined or null. In [1,,3], there is no element at index 1, though stringified versions may represent it as undefined, null or empty. Commented Dec 11, 2019 at 6:14
  • But if it's null or undefined, doesn't the engine check Array and Object prototypes, just in case? Commented Dec 11, 2019 at 6:14
  • 1
    No it doesn't check the prototype. The value is the value. Commented Dec 11, 2019 at 6:15
  • No, why would they? null and undefined are values just like any other. Commented Dec 11, 2019 at 6:15

1 Answer 1

2

No. The array object will still have an own-property at that array index:

const arr = [1, 2, 3];
arr[0] = null;
arr[1] = undefined;
console.log(arr.hasOwnProperty('0'));
console.log(arr.hasOwnProperty('1'));

Compare to a sparse array, which does not:

const arr = [ ,  , 3];
console.log(arr.hasOwnProperty('0'));
console.log(arr.hasOwnProperty('1'));

it's then flagged as sparse in modern browser engines and lookup speed is about the same as object key lookup - it needs to walk the prototype chain (a lot slower than index lookup).

Accessing indicies of normal non-sparse arrays indicies do have to walk the prototype chain if not found on the instance (though something will almost never be found):

Object.prototype[4] = 'foo';
const arr = [0, 1];
console.log(arr[4]);

If I were you, I'd use an object with numeric indicies instead, to avoid the sparse array. If there's a performance bottleneck in your script, it'll almost certainly not be in this section of code (which means that worrying about performance here won't really help).

Sign up to request clarification or add additional context in comments.

4 Comments

Yeah, forgot to mention that out of bounds index access also walks the prototype chain. Here's a good video abot the subject.
Non-out-of-bounds index access walks the prototype chain too, as you can see by the last snippet
This is an important subject for me because I have to loop quite big arrays in each frame and every millisecond counts.
You can also consider using a Map instead of an object or array - Map.get doesn't iterate over the internal prototypes, and IIRC is more suited for collections with dynamic "properties".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.