Why is the behavior of the undefined variable different from the undefined property?

Asked

Viewed 216 times

4

I’ve noticed this for a long time in Javascript.

If I write a certain code where the variable is not defined in any scope, an exception is thrown:

console.log(preco)

Upshot:

Uncaught Referenceerror: preco is not defined

But if I try to access an undefined property, no errors are released, but only undefined is returned:

  var obj = {};

  console.log(obj.id); // undefined
  console.log(window.preco); // undefined

Why Javascript Behaves This Way?

3 answers

3

Because of the nature of both.

The variable is something more concrete in the language, it must exist in the code, has how to verify and know if it exists or not.

The property of an object looks like a variable, but is not, is just a key in a array associative. There is no way the JS interpreter can be sure if it exists or not, there can be one time, there is no other time. JS objects are open for dynamic modification in their structure at any time.

obj.id

actually is

obj["id"]

Of course there could be a way to detect the problem and generate an error, but resolve to be consistent with the table mechanism used in array associative which is to consider that the element that does not exist is only undefined and does not generate an error. The way to know if a key exists is to compare it to undefined.

So if you access the element in the table, no error occurs, even if it does not exist, it is just a non-existent key at that time. Dynamic typing languages have this advantage of being flexible and the disadvantage of being less robust and requiring the programmer to worry about doing it right, testing before using, either by unit testing, or by testing in the same code, if it can turn around if an error occurs.

var obj = {
    a : 1
};
console.log(obj.a);
console.log(obj.b);
if (obj.b == undefined) console.log("propriedade não existe");
obj.b = 2;
console.log(obj.b);
for (var chave in obj) console.log(chave + " = " + obj[chave]);

I put in the Github for future reference.

1

An undeclared variable is not listed in Variableenvironment.

In his example:

console.log(preco)

That means the identifier preco is not solved for any object stored in VariableEnvironment; an exception indicating the non-definition is generated ( $ident is not defined).

A declared but not initialized variable receives the default value undefined, which is at the same time a property of the object global and one of primitive types of javascript. In his example:

var obj = {};
console.log(obj.id);

The estate id (which is nothing more than a key pointing to a member of the object’s property collection obj) does not point to any object.

However, the collection sought is not VariableEnvironment, but only the collection of properties: The value returned is the global undefined.

0

I don’t know exactly why it works like this, but what I’ve noticed is that the exception of an undefined variable helps us find out if it exists or not, whether it’s global or local.

try {
    aa
} catch(e) {
    // não existe
}

For object properties this makes it difficult to detect the presence of a property in older browsers (type Msie6), but thanks to the operator in this makes it possible, with one exception.

Anyway, it wouldn’t make sense for a non-existent property to make an exception, maybe they wanted to avoid problems with expressions:

!!b

Only from an exception be launched, the execution of that block to, there is not be a try/catch/finally to protect the exception.

Currently, to find out if the property of an object exists we need a native method or operator, the property can be undefined, any kind of value. Object#hasOwnProperty solves this, the operator in will do the same, only that deep, will verify if the specific property exists in the properties of the builders, also.

Warning¹: the name of all properties of an object/function are converts for string;
Notice²: both of them function and objects can keep properties in itself;
Warning³: all numeric values, strings, objects, functions and booleans can be indexed . or [...], least null and undefined

var a = {
    b: undefined
}

// Diz que a.b não existe
typeof a.b !== 'undefined'

// Diz que a.b existe
a in 'b'

// Diz que a.b existe
a.hasOwnProperty('b')

And this is the most commonly used way to check if a property exists:

// Se a.b for um valor verdadeiro,
// diz sim
!!a.b

Browser other questions tagged

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