How does Undefined return work?

Asked

Viewed 279 times

4

When a variable is declared, but it has no value assigned to it, theoretically it has no data, but it exists in memory and is ready to be used:

let myVariable;

But when trying to use it is the same variable as, for example, printing its value in the console is the value rotornado undefined:

let myVariable;

console.log(myVariable);

This value that has been returned which is undefined is really the value of the variable and from here the value of this variable is undefined? or it is only a value to inform that the variable has the undefined value, but continue with the value "nothing" in the computer memory?

This also happens, for example, with arrays when, you use the constructor Array() with a specified integer and positive numeric parameter in which the value is defined, for example 10 will have 10 positions with empty values and in which if you try to access it will also return undefined:

let myArray  = new Array(10);

console.log(`Posições: ${myArray.length}`);

for (let i = 0; i < myArray.length; i ++) {
    console.log(`Valor da posição ${i}: ${myArray[i]}`);
}

In a response from bfavaretto he mentions that:

Note that the array is not actually filled with Undefined; the output we see on the console is a consequence of how the toString method works.

In this mention he explains why he is returning undefined, but I didn’t understand what he meant.

This return it exists only to specify or confirm that the return value is undefined?

2 answers

2

undefined is a value, just as null is also a value. The code needs to know what is undefined to be able to work with him.

An uninitialized variable is only a region of memory that was acquired, but still contains content that was previously allocated in that region. There is no way your process knows that this junk represents an uninitialized value unless it initializes this variable with a value that represents not being initialized (this makes sense?)

undefined as well as null are pointers that point to a memory region that should not be accessed. Which region? Usually 0x00000000 or 0x00000001, but this is implementation detail, and it’s not up to the language to define this.

When you declare a variable but do not initialize it, the process itself will initialize it with the value undefined. The variable was actually initialized, with a value that represents not having been initialized by the programmer.

On the other hand, when you access an invalid property of an object or an array, by Javascript language rule, you will receive undefined, but that doesn’t mean that memory region contains the value undefined, That’s just the return defined by the rule... which can be a little ambiguous.

var arr = new Array(2);
arr[0] = undefined;

console.log(arr[0]);
console.log(arr[1]);

In the above example, the array has already been initialized with the capacity 2, the property 0 contains the value undefined, and the property 1 does not exist, which results in undefined. If there is a need to differentiate a value undefined and a non-existent property, you will need to turn to the operator in:

var arr = new Array(2);
arr[0] = undefined;

for (var i = 0; i < arr.length; i++) {
  if (i in arr) console.log(`A propriedade ${i} existe, e seu valor é ${arr[i]}`);
  else console.log(`A propriedade ${i} não existe, e portanto é retornado ${arr[i]}`);
}

2


First of all, it is worth remembering that Undefined is one of the types defined by the language (as well as String, Number, Boolean, etc.). And the specification says the following:

The Undefined type has Exactly one value, called Undefined. Any variable that has not been Assigned a value has the value Undefined.

I mean, the guy Undefined has only one value, which is undefined. And any variable to which no value has been assigned has the value undefined.

That is, by just doing let variavel;, the variable has the value undefined (and just to make it more confusing, there’s still one ownership of the global object called undefined whose value is - guess - undefined).


As for arrays, it is a little more complicated. Following explanation based in this reply by Soen.

The builder Array(n), when called with only one argument, and this argument is an integer, returns an array whose size (i.e., whose property value length) is this number.

But when trying to access any of the elements of it, the return is undefined:

let x = Array(2);
console.log(x.length); // 2
console.log(x[0], x[1]); // undefined, undefined
console.log(x);

Note: in the last line there may be divergences as to the output. Running on the site snippet, I got [undefined, undefined], but Chrome’s own console, the return was [empty x 2] and on the Node was [ <2 empty items> ].

What happens is that, although it seems, Array(2) is not the same thing as [undefined, undefined]. For example, if we map each element of the array to any value, using map:

console.log([undefined, undefined].map(e => 1));  // [1, 1]
console.log(new Array(2).map(e => 1));

On the last line, again there was the divergence: on the site snippet, the output was [undefined, undefined] and in Chrome and Node the output was respectively [empty x 2] and [ <2 empty items> ].

Finally, according to the specification, the builder Array(tamanho) only creates an array whose property value length is the size reported, and only. No element was actually created within it.

So by traveling it with map the result remains "2 Empty items", as the specification says that map checks whether the property of the array (the index, in this case) exists. But the array created with Array(tamanho) does not possess these properties:

function verificarIndices(array) {
    for (let i = 0; i < array.length; i++) {
        console.log(`tem ${i}? ${array.hasOwnProperty(i)}`);
    }
}

console.log('array de undefined');
verificarIndices([undefined, undefined]); // imprime "true" para os índices
console.log('Array(2)');
verificarIndices(Array(2));  // imprime "false" para os índices

console.log(Object.getOwnPropertyNames([undefined, undefined]));  // ['0', '1', 'length']
console.log(Object.getOwnPropertyNames(new Array(2))); // ['length']

Which leads us to conclude that the array has no elements, and undefined is just a value that is returned when an element does not exist. After all, this is what happens when we access an index that does not exist:

let x = [1, 2, 3];
console.log(x[999]); // undefined

Finally, another way to see the array created by Array(n) has no indices (and therefore we can conclude that it does not have the respective elements):

console.log('percorrendo [undefined, undefined]');
for (let i in [undefined, undefined])
    console.log(i); // imprime 0 e 1

console.log('percorrendo Array(2)');
for (let i in Array(2))
    console.log(i); // não imprime nada

console.log('--------');
console.log(Object.keys([undefined, undefined])); // [ '0', '1' ]
console.log(Object.keys(Array(2))); // []


What about the comment on toString, the specification says that toString calls internally the method join no arguments. And when join is called without arguments, the specification says a comma is used as a separator. The algorithm also says that if the element is undefined or null, the empty string is used in place. And as we have seen, the access to the non-existent elements of Array(2) returns undefined, the result of toString will be a bunch of commas (to be more precise, in an array of size N, will be N - 1 commas).

  • So for variables the undefined exists, but for arrays only at the moment it is accessed?

  • @felipecardozo In fact I believe that for objects in general, when trying to access a property that does not exist, it must have an "if (does not exist) returns Undefined" (and the indexes of an array in the background are properties of it). I didn’t find this excerpt from the specification but I’m pretty sure it should have - if I find it, update the answer

  • beauty :), thanks a lot!

  • @felipecardozo I did not find the excerpt of the specification, but I included another example in the answer. Perhaps now it is more clear that Array(2) in fact only arrow the size (length) but does not create the elements

  • Thanks, buddy! by the effort became clearer to me.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.