11

So I'm playing around with JavaScript and came across what I think to be an oddity. Is anyone able to explain the following? (i've included the alerted values as comments)

Why is the first alert(msg) inside foo() returning undefined and not outside?

var msg = 'outside';

function foo() {
  alert(msg); // undefined

  var msg = 'inside';
  alert(msg); // inside
}

foo();    
alert(msg); // outside

Considering these both work fine:

var msg = 'outside';

function foo() {
  alert(msg); // outside
}

alert(msg); // outside

and:

var msg = 'outside';

function foo() {
  var msg = 'inside';
  alert(msg); // inside
}

alert(msg); // outside
4
  • Can you show the full context of the 1st script? Commented Apr 21, 2010 at 18:05
  • I forgot to add the call to foo(); but other than that, this is the full context of it. I was just playing around with variable scopes and came across this. Commented Apr 21, 2010 at 18:10
  • never mind, it's already solved, I was suspecting something else. Commented Apr 21, 2010 at 18:12
  • You cannot have at the same scope level, two variables with the same name.. Commented Apr 21, 2010 at 18:16

5 Answers 5

19

What is happening in your first example is the declaration and initlization of msg are being split with the declaration being hoisted to the top of the closure.

var msg; //declaration
msg = "inside" //initialization

Therefore the code you wrote is the same thing as

var msg = 'outside';

function foo() {
var msg;  
alert(msg); // undefined
msg = 'inside';
alert(msg); // inside
}

The second example is not the same. In your second example you have not declared a local variable msg so alert(msg) refers to the global msg. Here is some further reading on: Hoisting

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

7 Comments

Any other information as to why this is interpreted that way, considering the second example works without issue? It seems the same to me, only it has code following it...
I wasn't quite sure why I got the downvote either. Either way, like the other answers that are appearing here, the reason is variable declarations in javascript are hoisted. This means that they are moved to the top of the closure.
@Cory the second example has no var msg in it. The var makes it a local variable, and the twist is it makes it so even before the physical location of the var.
@Shaun ah, gotcha! Thanks for the insight! Didn't know var's where hoisted. GREAT to know.
@Shaun by the time i've read your post the "var msg;" wasn't there and so i looked like nonsense to me.
|
3

Variable declarations inside a Javascript closure take place first, regardless of where they are located within the the closure. So in your first example, a local variables msg exists at the start of the function (because it is declared within the function) but a value is not assigned to it until after the first alert, so for that first alert, msg is undefined.

Your first example is equivalent to:

var msg = 'outside';

function foo() {
  var msg;
  alert(msg); // undefined

  msg = 'inside';
  alert(msg); // inside
}

alert(msg); // outside

In the second example, you don't explicitly declare msg within the function. Since there is already a global variable with the same name, the global is used instead of a local being defined.

In the third example, you explicitly declare the variable and assign it a value before trying to use it, so when you alert(msg), the local, defined variable is alerted.

Comments

2

from http://www.irt.org/script/1321.htm:

If we declare but not initalise a variable with the var keyword inside a function it should be local in scope, but undefined across the complete function until the point at which it is [initialized]...

this will work for you:

var msg = 'outside';

function foo() {
  alert(window.msg); // outside

  var msg = 'inside';
  alert(msg); // inside
}

alert(msg); // outside
foo();
alert(msg); // still "outside"

Comments

1

var is not a declaration. It is a confusion that mixes up many people. Rather, var is a scope-wide annotation. The placement of 'var' inside a scope does not matter.

var in JavaScript is an Annotation, not Statement

Comments

1

You can completely control the execution of java script functions and pass variables as a argument,

Here in this case function inside you can not access outside variable. but if you want to use you pass variable argument to access that value inside function.

var msg = 'outside';

function foo(msg) {
  alert(msg); // outside

  var msg = 'inside';
  alert(msg); // inside
}

foo(msg);    
alert(msg); // outside

Check this Demo jsFiddle

And inside another variable g you define is a 'private' variables (with in a function scope) so its alert "inside" value within function. Hope this help you!

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.