3

I'm trying to understand

function test() {
  return 'foo';
}

console.log(test());

test = function() {
  return 'bar';
}

console.log(test());

function test(a, b) {
  return 'baz';
}

console.log(test());
console.log(test(true));
console.log(test(1, 2));

the above code which consoles

baz
bar
bar
bar
bar

But being JavaScript a single-threaded language and function overloading concept I was expecting

foo
bar
bar
baz
baz

Could anyone explain why is this happening?

Chad Moore
  • 734
  • 4
  • 15
Ashvini Maurya
  • 493
  • 1
  • 7
  • 13

3 Answers3

2

Yep. I think what was happening is the following:

  1. Functions declared with function test(...) { ... } are hoisted to the top of current scope. So both definitions of your function using that syntax were hoisted to the top, but the second one defined overwrote the first one, thus the result 'baz.'

  2. Function expressions are not hoisted, e.g. test = function (...) {...}. So when you reassigned the identifier test to that function expression, it became the value for test for the remainder of your script.

As pointed out already, you cannot overload vars or functions in JavaScript. You can overwrite vars with new values, which is what you did in your example. What is confusing is the way that JavaScript hoisting works.

If you want to avoid hoisting use let myFn = function (...) { ... }.

Here's a line by line, as I understand it:

// `test` defined with func declaration, hoisted to top
function test() {
  return 'foo';
}

console.log(test);
console.log(test());

// `test` overwritten with function expression, hoisting has already occurred,
// `test` identifier will have this value for remainder of script
test = function() {
  return 'bar';
}

console.log(test);
console.log(test());

// `test` overwritten with new func declaration, hoisted to top, but after first declaration
function test(a, b) {
  return 'baz';
}

console.log(test);
console.log(test());
console.log(test(true));
console.log(test(1, 2));
Chad Moore
  • 734
  • 4
  • 15
2

Step by step :

function test() {
  return 'foo';
}

This is a function declaration. A test variable is declared when it's interpreted, before runtime.

test = function() {
  return 'bar';
}

This is a function expression. The test variable will be overwritten when this line is executed.

function test(a, b) {
  return 'baz';
}

This is another function declaration. The test variable is overwritten, again before runtime.

That's why your first version of the test function is never called. Because the second function declaration overwrote it before runtime.

More about function declaration vs. function expressions.

Guillaume Georges
  • 3,878
  • 3
  • 14
  • 32
0

Javascript function can't have overloads, they just get overwritten. To get the same effect you need to distinguish the different overloads inside your method.

function test(a, b) {
  if(b)
     return 'baz';
  return 'foo';
}
Sebastian Speitel
  • 7,166
  • 2
  • 19
  • 38
  • 1
    This doesn't fully explain what's happening though. Would you be willing to update your answer to give a line-by-line and step-by-step? e.g., function is declared and hoisted; function is declared and hoisted, overwriting; second function is called; declared function is overwritten by function expression, etc. – Fissure King Jun 27 '18 at 17:46