David W
David W

Reputation: 17

JS Global/Function Scope Understanding

I'm currently enrolled in a Javascript class and I wanted some help understanding how exactly scope works. We've been over topics like global scope, function scope, hoisting in class but I'm struggling to put it all together. So the question that I was specifically looking at consisted of figuring out what the following code outputted:

x = 1;
var a = 5;
var b = 10;
var c = function (a, b, c) {
    document.write(x);
    document.write(a);
    var f = function (a, b, c) {
        b = a;
        document.write(b);
        b = c;
        var x = 5;
    }
    f(a, b, c);
    document.write(b);
    var x = 10;
}
c(8, 9, 10);
document.write(b); 
document.write(x);

Now the solution that we have is that code will print out undefined 8 8 9 10 1

I needed some help understanding how exactly this happens. Specifically, I don't understand how the values of b vary depending on the statement we're looking at. Would appreciate it if someone could just run through the whole step-by-step for me. Thanks!

Upvotes: 0

Views: 74

Answers (1)

Miguel
Miguel

Reputation: 20633

I commented the code a little so hopefully it makes more sense. The most important concepts to understand is variable hoisting and function scope. There is only function scope in JavaScript.

x = 1;
var a = 5;
var b = 10;
var c = function (a, b, c) {

    /* this `x` refers to the new `x` variable initialized below
     * near the closing function `c` brace.
     * It is undefined because of hoisting, and gets assigned
     * a value where it was initialized below.
     */
    console.log(x); // undefined

    /* this `a` refers to this `a` parameter,
     * because it is within this function `c` scope.
     */
    console.log(a);

    var f = function (a, b, c) {

        /* this `b` refers to this `b` parameter,
         * because it is within this function `f` scope.
         *
         * this `a` refers to this `a` parameter,
         * because it is within this function `f` scope.
         */
        b = a;
        console.log(b);

         /* this `b` still refers to `b` in this function `f` scope.
          *
          * this `c` refers to this `c` parameter,
          * because it is within this function scope.
          */
        b = c;

        /* this is a new `x` variable because it is
         * with this function `f` scope and there is no parameter `x`.
         */
        var x = 5;
    };

    /* these `a`, `b`, and `c` variables refer to
     * this function `c` parameters.
     */
    f(a, b, c); // f(5, 10, 10)
    console.log(b); // 9

   /* this is a new `x` variable because it is
    * with this function `c` scope and there is no parameter `x`.
    */
    var x = 10;
};

c(8, 9, 10);

/* `a`, `b`, `c`, and `x` have not been touched,
 * because the other `a`,`b`,`c` variables were parameter names,
 * and other `x` variables were initialized within a different scope.
 */
console.log(b); // 10 
console.log(x); // 1

JSBin Demo

Upvotes: 1

Related Questions