3

I have trouble understanding JavaScript function level scope, as a C# programmer it looks wired to me, I will try to explain it through code:

CODE#1

//Problem
//if same named variable (as in global scope) is used inside function scope,
//then variable defined inside function will be used,global one will be shadowed
var a = 123;
function func() {
    alert(a); //returns undefined,why not just return 123 ?
    //how come js knew that there is variable 'a' will be defined and used in 
    //this function scope ,js is interpreter based ?
    var a = 1; //a is defined inside function
    alert(a); //returns 1 
}
func();

CODE#2

//when a variable(inside function) not named as same as the global,
//then it can be used inside function,and global variable is not shadowed
var k = 123;
function func2() {
    alert(k); //returns 123 ,why not 'undefined'
    var c = 1;
    alert(c); //returns 1
}
func2();

So my questions are

  1. in CODE#1 why first time a is undefined,why not it's just return 123? And how come js knew that there is variable 'a' will be defined and used in this function scope, js is interpreter based?

  2. in CODE#2 why not k is 'undefined'?

http://jsfiddle.net/Nu2Vu/

2
  • 2
    This is called hoisting in js adequatelygood.com/JavaScript-Scoping-and-Hoisting.html Commented Apr 14, 2013 at 18:01
  • btw hoising is not the same as function level scope. try for example (in firefox) the same, with let instead of var.it does the same thing, and let has block level scope Commented Apr 14, 2013 at 18:10

2 Answers 2

7

CODE #1

Hoisting causes all variable declarations to be brought to the top of the scope, but it leaves the assignment where it is. When there is a reference to a variable JavaScript will first look in the current scope, if it doesn't find the variable it will continue to look up the scope chain until if finds the variable. This code is interpreted something like this:

var a = 123; // global var named a declared, assigned a value
function func() {
  var a; // the declaration of the local var a gets
         // hoisted to the top of the scope, but the
         // assignment is left below, so at the point
         // it is initialized with a value of `undefined`
    alert(a); // looks for a local var named a, finds it but
              // it currently has a value of `undefined`

    a = 1; // now the value is assigned to the local a
    alert(a); // returns 1 
}
func();

CODE #2

This code behaves the way it does because of closure. A basic definition of closure is that JavaScript functions have access not only to variables defined in their own scope, they can also access variables available to their parent scope.

var k = 123; // declares and assigns a value to global k
function func2() {
    alert(k); // looks for a local var named k, doesn't find it,
              // looks in its parent scope (the global scope in
              // this case) finds k, returns its value of 123
    var c = 1;
    alert(c); //returns 1
}
func2();
Sign up to request clarification or add additional context in comments.

Comments

5

The first code is equal to this:

var a = 123;
function func() {
    var a; //Undefined!
    alert(a); 
    a = 1; 
    alert(a); 
}

This explains it pretty well: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/var

2 Comments

Just wanted to add that this is called "Variable Hoisting".
@Ben thanks for introducing me to the term ,I didn't knew this :)

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.