简体   繁体   中英

(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.

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); 

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM