todofixthis
todofixthis

Reputation: 1142

(Why) does setting `array[NaN]` do nothing?

I was reading an article about javascript PRNGs, and I came across something that surprised me:

var a = new Array();
var b;
a[b++] = 1;

a is now [] and no exception is thrown — the write to the array simply vanishes. Try it out in your browser console if you don’t believe me.

I didn't believe him, so I tried it out in my browser console (Firefox 47):

» var a = new Array();
» var b;
» a[b++] = 1

» a
← Array [  ]
» b
← NaN

There are several curious things going on here, but in particular, I'm trying to understand why the statement a[b++] = 1 doesn't [appear to] do anything.

Upvotes: 0

Views: 75

Answers (2)

Andreas Louv
Andreas Louv

Reputation: 47119

Taking it from the top:

var a = new Array();
// 'a' is now an empty array, plain ol' boring empty array, could have been 
// written as a = [];
var b;
// 'b' have no value and is 'undefined'. 'console.log(b); // undefined'
a[b++] = 1;
// Lets break the above statement down into pieces:
  b++       // Increment b by one, undefined + 1 === NaN
a[   ]      // Use NaN as a property for our array 'a'
       = 1; // Assign 1 to that property
// Ok? So what happened why does 'a' still look empty?
console.log(a); // []
// The way your console with show you an array is by printing the numeric keys
// in it, and looking at the length, eg:
// var q = [];
// q.length = 1;
// console.log(q); // [undefined x 1]

// With 'a' in our case there is no numeric keys in it so [] is printed.
// So did our value dissapear?
// No. It is there:
console.log('NaN' in a); // true
// And:
for (var prop in a) console.log(prop); // NaN

// Why is this even a feature? 
// Arrays are extending Objects so they have the same properties as em.
console.log(a instanceof Object); // true
console.log(a instanceof Array); // true

Upvotes: 1

zerkms
zerkms

Reputation: 255015

There is a lot of stuff happening there.

  1. The code does something - it assigns the value 1 to the a[NaN]. And as soon as JS objects can only have string properties - the NaN is implicitly casted to a string, so in fact you have assigned 1 to a["NaN"] or a.NaN.

  2. The console object is not standardised, so you cannot expect anything particular from it. The current implementation in FF though iterates through the array indexes. "NaN" is not an array index, since it's not even numerical, so there is nothing shown in the console.

var a = new Array();
var b;
a[b++] = 1;

console.log(a[NaN], a["NaN"], a.NaN);

Upvotes: 1

Related Questions