2

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

1
  • 2
    Note that undefined is a value rather than an object. Commented Sep 18, 2012 at 22:00

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

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

Foo();

will also give you undefined.

this.bar means this["bar"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.