DEV Community

When is an array, not an array?

Joe Zack on November 20, 2018

TL;DR: Don’t do weird stuff to JavaScript arrays. *ahem* What are arrays? In the standard definition of Array data structures in Com...
Collapse
 
joelnet profile image
JavaScript Joel

This Array is not an Array!

const objArray = { 0: 'first', 1: 'second', 2: 'third', length: 3 }
objArray.__proto__ = Object.create(Array.prototype)

objArray.map(x => x.toUpperCase()) //=> ​​​​​[ 'FIRST', 'SECOND', 'THIRD' ]​​​​​
objArray.push('fourth')

objArray //=> Array { [Iterator]  0: 'first', 1: 'second', 2: 'third', 3: 'fourth', length: 4 }​​​​​

Object.prototype.toString(objArray) //=> "[object Object]"
Collapse
 
thejoezack profile image
Joe Zack

Haha, that is disgusting! I love it!

Collapse
 
antogarand profile image
Antony Garand • Edited

This weird behavior is caused by arrays, which are actually JavaScript objects!

console.log(typeof [1,2,3]);  
// object  

As they are objects, they can still have properties and other content injected via the bracket notation.

We can confirm this by checking the keys vs the array length:

const x = [1,2,3];  
console.log(x.length);  
// 3  
x[-1] = -1;  
console.log(Object.keys(x));  
// Array(4) [ "0", "1", "2", "-1" ]  
console.log(x.length);  
// 3  

When adding a value at a super high index, it behaves somewhat like a normal array:

const x = [1,2,3];  
x[100000] = `high`;
console.log(x.length);
// 100001
console.log(x);
// Array(100001) [ 0...9999] [10000...19999] ...

Love your podcast btw!

Collapse
 
thejoezack profile image
Joe Zack

Hey thanks!

Also, did you know that you can set the length property?

Check this out:

var x = [1,2,3,4,5];
x.length = 2;
// end up with [1,2]
Collapse
 
antogarand profile image
Antony Garand

Yea, that's a nice way to trim the end of an array!

Interesting but weird behavior, it suits JS

Collapse
 
kritner profile image
Russ Hammett

Ayyy solar panel array! My dude!

Collapse
 
thejoezack profile image
Joe Zack

Solar FTW!

Collapse
 
dance2die profile image
Sung M. Kim

I didn't get the featured image until you mentioned it 😆

Collapse
 
askeroff profile image
Javid Asgarov

Just a few days back I was reading about data structures, arrays and linked lists and wondered that I should take a look how arrays in javascript work, data-structure-wise. I mean, with arrays as a data structure, it seems you need to know array size beforehand, and then if it needs to grow you must reallocate memory and all that hideous stuff.

So, yeah, there a lot going on. Well, at least as I understood from this article, it's the array data structure under the hood, it just shifts it's in memory for you. But that data structure can also change to something else.

Collapse
 
thejoezack profile image
Joe Zack

Yep! Looks like the "normal" use case is generally implemented as a dynamic array underneath. So the engine will pick an array size to start, and if you exceed it then it will create a new bigger array. This is supposed to work really well in practice, since it's not common to individually add so many items to an array. I would love to know the default starting size!

en.wikipedia.org/wiki/Dynamic_array

Collapse
 
dance2die profile image
Sung M. Kim • Edited

Thanks Joe for the post.

Is an "array data structure" a superset of "array type"?
or are they not related at all?

Collapse
 
thejoezack profile image
Joe Zack

Types refer to the language implimentations, basically it's whatever looks like an array and
a specific language says is an array.

The data structure definition is more formal: contiguos memory allocation of the same sized element so you can achieve random access (as in, lookup any) in constant time.

In some languages, array types are implimented with array data structures (like C#) but JavaScript is a bit more complicated because it has to support a flexible language specification.

Collapse
 
dance2die profile image
Sung M. Kim • Edited

Borrowing C# analogy,

Types refer to an interface while data structure is a type of implementation implementing the interface.

Am I getting close to the truthiness? 😆

Thread Thread
 
thejoezack profile image
Joe Zack

I like it!