3

Please consider this code :

function A() {
    console.log("first");
}

var f = A;

function A() {
    console.log("second");
}

var g = A;

f();
g();

It outputs "first", "second" in firebug, which is what I thought it should do.
But it outputs "second", "second", in Chrome's console, or in firefox (when executing from a file, not in firebug).
Why should the reference kept in 'f' be changed I do the second "function A() {" ??

It seems like hoisting is the problem (see apsillers' answer bellow). But then, why does this example work correctly (I mean output first-second) :

var A = function A() {
    console.log("first");
}

var f = A;

A = function A() {
    console.log("second");
}

var g = A;

f();
g();

The fact that I used "A = ..." in the second function declaration blocks the hoisting of this function ?

Sebastien
  • 115
  • 9

1 Answers1

7

Function declarations are hoisted to the top of their scope, so your code is interpreted like so:

function A() {
    console.log("first");
}

// overwrite previous A
function A() {
    console.log("second");
}

// variable declarations are hoisted as well
// (not directly related to your problem here, but worth noting)
var f;
var g;

f = A;
g = A;

f();
g();

which produces the output of second, second in any modern browser.

In your second example, with var A = ..., you're now using function expressions, rather than function declarations. Function expressions are not hoisted.

Firebug weirdness

It appears that -- for some reason -- Firebug doesn't correctly perform function declaration hoisting:

console.log(bar);  // this line incorrectly produces a ReferenceError!

function bar() { }

This code snippet should log function bar() { }. It does so in any proper browser environment, but not Firebug.

EDIT:

The reason for the Firebug behavior is that Firebug code runs inside of a block, and function declarations are not valid in blocks. However, browsers will still handle them in non-strict mode, but how they handle them differs. Firefox treats them as unhoisted (while IE and Chrome do hoist them, as it happens).

Community
  • 1
  • 1
apsillers
  • 112,806
  • 17
  • 235
  • 239
  • Actually `var g` comes before `f = A`. – kapa Jun 05 '13 at 15:38
  • 1
    Right, I'll make the non-function hoisting behavior explicit as well. – apsillers Jun 05 '13 at 15:40
  • 1
    good answer, but then, why does this print "first", "second" correctly : var A = function A() [...] A = function A() ?? (I edited my question with the complete new code) – Sebastien Jun 05 '13 at 15:43
  • ok actually your link contains the explanation (see the conclusion, function expression versus function declaration). thanks ! – Sebastien Jun 05 '13 at 15:55