1

In my understanding defining a variable without the var keyword just evaluates to adding this variable to the window object. And on the other hand, trying to access a member of an object, that isn't yet defined, evaluates to undefined. So I can do things like this:

> foo = "bar";
"bar"
> window.foo;
"bar"
> window.bar;
undefined

Why am I not able to get an undefined variables value (undefined) when accessing it directly?

> bar;
ReferenceError: bar is not defined

There is another thing that I don't quite get, that I think could be related. When I type some literals into the console, they always evaluate to themselves. 1 evaluates to 1, [1] to [1] and so on. I always thought of a function to also be a literal because it has some value-like qualities (beeing first class citizen). But when I try to evaluate an anonymous function, I get a syntax error.

> function() {}
SyntaxError: Unexpected token (

I know that I can define a named function, but that evaluates to undefined (it defines the function somewhere rather then being it itself). So why arent functions literals?

thanks

David G
  • 94,763
  • 41
  • 167
  • 253
sra
  • 6,338
  • 3
  • 20
  • 17

3 Answers3

3

For the first part of your question, see ReferenceError and the global object. Basically, explicitly referencing a non-existent property of an object will return undefined because there may be cases where you would want to handle that and recover. Referencing a variable that doesn't exist should never happen, though, so it will fail loudly.

For the second part of your question, you are trying to declare a function without a name, which isn't possible. There's a subtle difference between a function declaration and a function expression. Function expressions, for which the function name is optional, can only appear as a part of an expression, not a statement. So these are legal:

var foo = function () { };

(function () { });

But not this:

function () { };

Community
  • 1
  • 1
jonvuri
  • 5,738
  • 3
  • 24
  • 32
  • I was not aware of the fact that a function expression can only be part of a bigger expression. I guess this is what makes it different from say a number or string which certainly evaluate to themselves no mather if on their own or as part of an expression. It's a little sad because it would have fit perfectly into my understanding, if a function simply was a literal like a sophisticated object can be :) – sra Sep 15 '12 at 17:06
0

If you just access 'bar', the scope is unclear. The variable is first sought in the local scope (if your inside a function). If it's not found there' the window object is checked. But any error you get logically refers to the 'bar' that doesn't exist in the local scope.

What would you expect to be displayed if you want to show a function like that? A function has no value and its declaration certainly hasn't. You could expect the console to be able to execute a function and return the result, but that's also dangerous. Not only can you have a function that doesn't return a value, but also, functions can contain code that modify their environment, in other words, running a function in the console could modify the current state of the document and the current Javascript state in it.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • I would expect the function to be evaluated as a function just like a string gets evaluated to a string. When you type any existing function in the console without the parantheses, you'll see it beeing printed. Why does that not happen when I try to define a function like descriped? – sra Sep 15 '12 at 16:21
  • Your answer re: functions is very confusing... You certainly can inline a function value (Yes, it's a first-class value in Javascript) as long as it's part of an expression, and you can also execute an anonymous function. Both, respectively: `(function(){})` `(function(){}())` – jonvuri Sep 15 '12 at 16:40
  • wow.. how many times have I used `(function(){})()` to define and execute an anonymous function. but still wasn't aware of the outer parantheses function. – sra Sep 15 '12 at 17:11
0

Javascript has been coded such that if you try to read a property of an object, you get undefined.

But, if you try to read the value of a variable that doesn't exist without referencing it as a property of the global object, it throws an error.

One could explain this choice a number of ways, but you'd have to interview one of the original designers to find out exactly why they chose it. The good news is that once you understand the behavior, you can code it one way or the other depending upon which behavior you want. If you know a global variable might not be defined, then you can preface it with window.xxx and check for undefined.

In any case, if you want to test if a global variable exists, you can do so like this:

if (typeof bar !== "undefined")

or

if (window.bar !== undefined)

Also, be very careful about assuming the console is exactly the same as a real javascript execution because it's not quite the same in a number of ways. If you're testing a borderline behavior, it's best to test it in the actual javascript execution context (I find jsFiddle very useful for that).

jfriend00
  • 683,504
  • 96
  • 985
  • 979