sra
sra

Reputation: 6418

why is window.foo undefined whereas a call to foo throws an error?

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

Upvotes: 1

Views: 3185

Answers (3)

jfriend00
jfriend00

Reputation: 708156

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).

Upvotes: 0

jonvuri
jonvuri

Reputation: 5940

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 () { };

Upvotes: 3

GolezTrol
GolezTrol

Reputation: 116200

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.

Upvotes: 0

Related Questions