0

I have two functions name init

One is declared using function declaration and another using function expression, like this:

function init() {
    alert ('init 1'); 
}

var init = function(){
    alert('init 2');
}

init();

When i call the init function it alerts init 2.

Demo

My question is:

1- Why javascript does not throw error as both functions have same name.

2- How can i call the first function?

Nabeel Bape
  • 60
  • 1
  • 9
  • Second init is not a function, and the first one is called through a simple statement like, `init();` http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname – VPK Oct 10 '14 at 11:56
  • init(); calls the second method not first one, check my fiddle. – Nabeel Bape Oct 10 '14 at 11:57

6 Answers6

3

Why javascript does not throw error as both functions have same name.

They don't have the same name. The second is a variable init containing an anonymous function. The first is a function named init.

You can test this by doing the following on both:

console.log(init.name);

You'll see that the first does indeed have a name init, whereas the second has no name.

How can i call the first function?

In this example the first can't be called after using init for your variable for the second. Unless you have another reference to the first like so:

function init() {
        alert ('init 1'); 
}
var original = init;
MrCode
  • 59,851
  • 9
  • 76
  • 106
  • 1
    Although pedants may wish to draw a distinction between a named function and an anonymous function assigned to a named variable, and there are indeed differences between the two, in everyday practice the simple fact is just that both kinds of names share the local scope, and cannot exist at the same time with the same name. The OP's question was merely why doesn't JS report this as an error like other languages do (answer: because it doesn't), and once I've overwritten a name in the local scope can I get back the old version (answer: you can't). –  Oct 10 '14 at 12:08
  • *They don't have the same name.* Actually, this is **NOT** the reason JS doesn't throw an error. If it was, one might expect that `function foo() {} function foo() {}` or `var x=1; var x=1;` **would** throw an error, but they don't either. The reason JS doesn't throw an error is because, well, **JS doesn't throw an error in cases of variable or function redefinition or reassignment**. Whether it's a variable or a function is irrelevant. –  Oct 10 '14 at 12:18
2

There is nothing fundamentally different between what you are doing and

var i = 1;
var i = 2;

No, JS does not throw an error, and no, once you've redefined i you can't get the old value back.

In ES6 and some modern browsers, you can say

const i = 1;

and then the engine will complain if it's redefined.

2

Declarations in JavaScript are hoisted. A function declaration is one type of a declaration. Hence your program is equivalent to:

var init = function init() {
    alert("init 1");
};

var init = function () {
    alert("init 2");
};

init();

If you call init before your second definition then it would alert init 1:

function init() {
    alert("init 1");
}

init();

var init = function () {
    alert("init 2");
};

Because of hoisting you can even call init before it appears in the program:

init();

function init() {
    alert("init 1");
}

var init = function () {
    alert("init 2");
};

Just remember than no matter in what order they appear in the program, the function declaration always comes first:

init();

var init = function () {
    alert("init 2");
};

function init() {
    alert("init 1");
}

Hope that helps.

Aadit M Shah
  • 67,342
  • 26
  • 146
  • 271
  • Excellent summary of hoisting, but what does it have to do with the OP's question? –  Oct 10 '14 at 12:03
  • 1
    i know about hoisting, i want to know what happens to my first function, is it getting overridden by the second one or does it still exists in global name space? – Nabeel Bape Oct 10 '14 at 12:10
0

Javascript gets the last defination of function. You can rename it unique or you can "use strict" to make it local function.

function functions(){
    "use strict"
    var init = function(){
        console.log("b");
    };

    return {
        start : init
    }
};

var fn = new functions();
fn.start();
Gurkan İlleez
  • 941
  • 6
  • 11
  • Not getting the part about "using `use strict;` to make it local function". –  Oct 10 '14 at 12:02
0

You can make kind of namespace:

var p1 = {
  init: function() {
    alert('init 1');
  }
};

var p2 = {
  init: function() {
    alert('init 2');
  }
};

var init = function() {
  p1.init();
  p2.init();
};

init();
Running ...
0

This works:

function init() {
    alert ('init 1'); 
}

var init = (function(oldInit) { return function() {
  oldInit(); // Call the first definition this way
  alert('init 2');
}; })(init);

init();

The trick is to have the second init() remember the previous init. Javascript doesn't throw an error because it's often useful to redefine functions.