3

When I try to use an undeclared variable I get ReferenceError:

console.log(a); // Uncaught ReferenceError: a is not defined

I could use a variable first and define it later and it won’t be a problem due to hoisting.

console.log(a); // undefined

var a;

But when I declare an object why would the execution context let me use any property of it?

var obj = {};

console.log(obj.a); // undefined
console.log(obj.why); // undefined

Why are these allowed even though a and why are never declared anywhere?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
dogant
  • 1,376
  • 1
  • 10
  • 23
  • Not exactly a *duplicate*, but a good explanation on the difference: http://stackoverflow.com/questions/10102862/referenceerror-and-the-global-object – CodingIntrigue Aug 09 '15 at 07:42
  • Related (about the difference between variables and properties): [var vs this in Javascript object](/q/4946625/4642212). – Sebastian Simon Sep 19 '21 at 04:49

2 Answers2

5

Because object properties are not variables. The rules are different. Accessing an object property that doesn't exist gives you undefined, not an error. It's just the way the language is designed.

One possible explanation for the difference, other than just that "that's how Eich designed it," is that you don't declare object properties. You just use them. But variables must be declared (other than The Horror of Implicit Globals, and we don't have that now we have strict mode).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
3

The language design has specified that trying to access a non existent property on an object will simply return undefined.

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

But, that trying to access a variable that is not defined anywhere within the current or parent scopes is a ReferenceError.

console.log(b);       // ReferenceError

Why are these allowed even though a and why are never declared anywhere?

It's just the way the language is designed. I can see some reasons for it to be this way, but the real reason that it was decided to make it this way is only in the heads of some of the original designers. Our job at this point is to understand how it works and write code that is compatible with the current design (since we can't change the current language design).


There are ways to work-around this issue by testing for these undefined variables such as:

if (typeof b === "undefined")

Or, if you're in a browser and you're expecting b to be a global, you can use the fact that globals are attached to the window object and that missing object properties don't create ReferenceErrors like this:

console.log(window.b);   // undefined
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • "I can see some reasons for it to be this way" what do you think they are? I'd like to know to understand the internals better – dogant Aug 09 '15 at 07:54
  • @wheee - the consequences of accidentally referring to variables that are not defined when you didn't mean to can be pretty messy or confusing in downstream code. It seems a reasonable line in the sand to draw and say that this is likely an unintended thing and should throw an error, especially since there are ways to work-around it if you're actually purposely dealing with a possibly undefined variable. Yes, JS does let you shoot yourself in the foot other ways, but a line does have to be drawn somewhere and they decided to draw one line here. – jfriend00 Aug 09 '15 at 07:57