4

Could anyone please explain what's the difference between the first example and the second example, please?

What's the difference between declared "undefined" value and undeclared "undefined" value?

Code

var arr = new Array(4);
arr[0] = "a";
arr[1] = "b";
arr[2] = undefined; //insert undefined here!
arr[3] = "d";
console.log("arr[2] is " + arr[2]); //yes, it is undefined!

arr.forEach(function(value, index) {
    console.log(index + ":" + value);
})

console.log("====================")

var arr = new Array(4);
arr[0] = "a";
arr[1] = "b";
//I don't insert undefined to arr[2] in this case.
arr[3] = "d";
console.log("arr[2] is " + arr[2]); //yes, it is undefined!

arr.forEach(function(value, index) {
    console.log(index + ":" + value);
})

Log

arr[2] is undefined
0:a
1:b
2:undefined
3:d
====================
arr[2] is undefined
0:a
1:b
3:d

Additional Example

var arr = new Array(4);
arr[0] = "a";
arr[1] = "b";
arr[2] = undefined; //insert undefined here!
arr[3] = "d";
console.log("arr[2] is " + arr[2]); //yes, it is undefined!

var i = 0;
var max = arr.length;
for(i; i < max; i++) {
console.log(i + ":" + arr[i]);
}

console.log("====================")

var arr = new Array(4);
arr[0] = "a";
arr[1] = "b";
//I don't insert undefined to arr[2] in this case.
arr[3] = "d";
console.log("arr[2] is " + arr[2]); //yes, it is undefined!

var i = 0;
var max = arr.length;
for(i; i < max; i++) {
console.log(i + ":" + arr[i]);
}   

Log

arr[2] is undefined
0:a
1:b
2:undefined
3:d
====================
arr[2] is undefined
0:a
1:b
2:undefined
3:d
  • 2
    one is initialized (in JS we say 'declared') but undefined; one isn't initialized and undefined – jeremy Jun 13 '16 at 03:59
  • Possible duplicate of [Are Javascript arrays sparse?](http://stackoverflow.com/questions/1510778/are-javascript-arrays-sparse) – Ramanlfc Jun 13 '16 at 04:03
  • 1
    @Ramanlfc this is not a duplicate of that question. it's clear OP understands this aspect – jeremy Jun 13 '16 at 04:04
  • @Jeremy Could you explain why forEach doesn't visit when a value is undeclared undefined but visits when a value is declared undefined? –  Jun 13 '16 at 04:37

2 Answers2

2

Could anyone please explain what's the difference between the first example and the second example, please?

In the first example:

var arr = new Array(4);

creates an array with length 4, it has no elements.

Then a value is assigned to indexes 0 to 3 using direct assignment:

arr[0] = "a";
arr[1] = "b";
arr[2] = undefined; //insert undefined here!
arr[3] = "d";

which creates properties 0 to 3. undefined is assigned to arr[2]. forEach iterates over elements that exist, so you see the result from all 4 elements, each with a value.

In the second example, you do not assign a value to arr[2]. When accessing a non–existent property of an object (noting that Arrays are Objects), the undefined value is returned, e.g.

var obj = {};
console.log(obj.foo) // undefined

When looping over the properties with forEach, non–existent properties aren't visited so there is no output for arr[2]. This is in contrast to for loops, which are generally written to visit all properties from 0 to length - 1 and hence return values for all properties in that range, whether they exist or not.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • thank you for pointing out the differencd between foreach and for. now im clear! –  Jun 13 '16 at 04:28
  • @Hayatomo—you may wish to review the [*forEach* polyfil on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill), which follows the steps in ECMA-262 and has an own property test at step 7.b (which is step 8.b. in [*ECMAScript 2015*](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.foreach) and 6.b in [*ECMAScript 2017*](https://tc39.github.io/ecma262/#sec-array.prototype.foreach)). – RobG Jun 13 '16 at 06:13
0

JavaScript arrays are not arrays in common sense. In most languages arrays (a.k.a. vectors) are contiguous areas in memory. But in JS they are rather sparse containers - some elements may not exist.

In fact arrays in JS are just objects (key/value maps) with the difference that integer keys are allowed:

var arr = {}; // object (key/value map), not array, sic!
arr[0] = "a";
arr[1] = "b"; 
// arr[2] deliberately omitted
arr[3] = "d";
console.log("arr[2] is " + arr[2]); // it is undefined

You can even add non-integer keys to JS arrays:

var arr = [];
arr[0] = 0;
arr["zero"] = "zero";

This proves that arrays are objects under the hood.

When you try to get from a container (object or array) value of non-existent key it returns undefined value. By ECMAScript specification.

arr[2] = undefined assigns that value to key 2.

delete arr[2] removes that key and its value.

c-smile
  • 26,734
  • 7
  • 59
  • 86
  • 1
    "with the difference that integer keys are allowed" --- this is vague (and not 100% correct): 1. They are still converted to strings 2. Objects can also hold "numeric" keys. – zerkms Jun 13 '16 at 04:22
  • Whether arrays are "contiguous in memory" or not isn't relevant. Integer keys are allowed on all objects, not just arrays (which, as you say, are just Objects with a special *length* property and some handy inherited methods that are mostly generic and can be applied to other objects too). – RobG Jun 13 '16 at 04:25
  • @RobG " Integer keys are allowed on all objects". Negative in ES5, try this https://jsfiddle.net/ok3b4tg8/ . Indexes in objects are strictly strings. Even you will use numeric value it will be converted to string. `Object.keys()` cannot return anything but vector of strings. – c-smile Jun 13 '16 at 04:33
  • "Even you will use numeric value it will be converted to string" --- that's correct. And now it contradicts with yours "In fact arrays in JS are just objects (key/value maps) with the difference that integer keys are allowed" – zerkms Jun 13 '16 at 05:15
  • @c-smile—integer is not a type in javascript. I understood your original statement "*…with the difference that integer keys are allowed…*" to mean integers allowed as keys, i.e. strings (noting that integers of type string and number are largely interchangeable in ECMAScript except for addition). – RobG Jun 13 '16 at 06:01
  • @RobG "string and number are largely interchangeable " not always. Indexes in Arrays must be integers (Number.isInteger(value) -> true). Otherwise they are not indexes but keys, check this: https://jsfiddle.net/ujxp186b/ – c-smile Jun 13 '16 at 14:49
  • @c-smile—please don't misquote when replying: "***…integers** of type string and number are largely interchangeable*…", which also means "not always". – RobG Jun 13 '16 at 22:28