0

I preface this by saying I know that use of with is highly discouraged, and I don't intend on using it either. I'm just curious about learning how it works (I'm trying to figure out scope in javascript).

If I have some code like this:

function foo(obj) {
    with (obj) {
        b = 2;
    }
}

var o1 = {
    a: "something"
};

foo( o1 );
console.log(o1.b) // This outputs undefined (makes sense)
console.log(b) // This outputs 2 (makes sense)

However, if I change foo to something like this:

function foo(obj) {
    with (obj) {
        var b = 2; // I use var b instead of b
    }
}

When I pass in o1 to foo, again, o1 has no attribute b. Why is this? I thought using var would declare b inside the scope of obj, so the attribute would be created inside o1 instead of in the global scope.

Andi Gu
  • 900
  • 11
  • 20

2 Answers2

2

var declarations are hoisted. So what you are executing is equivalent to

function foo(obj) {
    var b;
    with (obj) {
        b = 2;
    }
}

It doesn't matter that the declaration is inside a with block. ยง9.2.12 describes what happens when the function body is evaluated. In step 11/12, all variable declarations are collected. A with statement simply "forwards" all the declarations inside of it (see spec).

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
1

Variable declarations (using var) do not respect block scope and instead are hoisted to the top of the scope. As far as the compiler/interpreter is concerned, your code is actually:

function foo(obj) {
    var b = undefined;
    with (obj) {
        b = 2;
    }
}
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91