Samuel
Samuel

Reputation: 12341

Accessing property of object vs variable in javascript

Why when I try to access a variable that don't exist, javascript throw an exception but when I try to access a property that don't exist in an object, javascript returns an undefined value?

For example, this case returns an undefined value:

function Foo(){
    console.log(this.bar);
}

Foo();

But, in this other example, javascript throw an exception:

function Foo(){
    console.log(bar);
}

Foo();

ReferenceError: bar is not defined

Upvotes: 2

Views: 992

Answers (3)

RobG
RobG

Reputation: 147403

Property resolution is fundamentally different to identifier resolution. The trivial answer is that ECMA-262 specifies that attempting to read a non–existent variable will throw an error, while attempting to read a non–existent object property does not, it just returns the special undefined value.

To get the reason, you'll need to aks Brendan Eich, who first developed JavaScript, on which ECMA-262 is based. However, a reasonable guess is that Brendan wanted to make JavaScript a simple language with loose typing, so rather than having to do something like:

if ( 'foo' in obj) {
  /* do something with obj.foo */
}

every time you want to access a property for the first time, the language was made tolerant of attempts to access undefined properties.

On the other hand, applying the same approach to variables would have created more issues than is solves, so typeof can be used to see if an identifier exists:

if (typeof foo != 'undefined') {
  /* ok to use foo */
}

Otherwise, property and identifier resolution are quite similar. The difference is that the first proceeds from an object, along a string of internal [[Prototype]] objects (the inheritance chain) and finally to the null object, whereas variable resolution proceeds from the local variable object along a string of similar objects belonging to outer contexts (the scope chain) to the global object.

Upvotes: 1

totten
totten

Reputation: 2817

function Foo(){
    console.log(window.bar);
}

Foo();

will also give you undefined.

this.bar means this["bar"]

Upvotes: 0

Alex Pakka
Alex Pakka

Reputation: 9706

As every object in JavaScript is a dictionary, also known as map in other languages, this.bar is equivalent to this['bar'], i.e. access to a value by a key. In most languages, e.g. in Java, returning null, NULL, or undefined allows you to conditionally create this slot if it does not exist yet, without dealing with exceptions or any other side effects.

However, when you just write console.log(bar) without specifying a context for the bar, it would be impossible to create a reasonable pattern where returning undefined would have a semantic meaning. There are multiple contexts, some of them dynamic, like global context window in the browser, where the bar might be defined during the runtime, so it cannot be a compile time error (as opposed to Java or C++). Hence runtime exception is thrown when variable name cannot be resolved.

Upvotes: 3

Related Questions