Function declarations versus function expressions versus the function constructor

What is the difference between these three statements?

function foo(n){ return n; }
var foo = function(n){ return n; };
var foo = new Function('n', 'return n');

At first glance, they're merely different ways to write the same function. But there's a little more going on here. And if we're to take full advantage of functions in JavaScript in order to manipulate them into a functional programming style, then we'd better be able to get this right. If there is a better way to do something in computer programming, then that one way should be the only way.

Function declarations

Function declarations, sometimes called function statements, define a function by using the function keyword.

function foo(n) {
  return n;
}

Functions that are declared with this syntax are hoisted to the top of the current scope. What this actually means is that, even if the function is defined several lines down, JavaScript knows about it and can use it earlier in the scope. For example, the following will correctly print 6 to the console:

foo(2,3);
function foo(n, m) {
  console.log(n*m);
}

Function expressions

Named functions can also be defined as an expression by defining an anonymous function and assigning it to a variable.

var bar = function(n, m) {
  console.log(n*m);
};

They are not hoisted like function declarations are. This is because, while function declarations are hoisted, variable declarations are not. For example, this will not work and will throw an error:

bar(2,3);
var bar = function(n, m) {
  console.log(n*m);
};

In functional programming, we're going to want to use function expressions so we can treat the functions like variables, making them available to be used as callbacks and arguments to higher-order functions such as map() functions. Defining functions as expressions makes it more obvious that they're variables assigned to a function. Also, if we're going to write functions in one style, we should write all functions in that style for the sake of consistency and clarity.

The function constructor

JavaScript actually has a third way to create functions: with the Function() constructor. Just like function expressions, functions defined with the Function() constructor are not hoisted.

var func = new Function('n','m','return n+m');
func(2,3); // returns 5

But the Function() constructor is not only confusing, it is also highly dangerous. No syntax correction can happen, no optimization is possible. It's far easier, safer, and less confusing to write the same function as follows:

var func = function(n,m){return n+m};
func(2,3); // returns 5

Unpredictable behavior

So the difference is that function declarations are hoisted while function expressions are not. This can cause unexpected things to happen. Consider the following:

function foo() {
  return 'hi';
}
console.log(foo());
function foo() {
  return 'hello';
}

What's actually printed to the console is hello. This is due to the fact that the second definition of the foo() function is hoisted to the top, making it the definition that is actually used by the JavaScript interpreter.

While at first this may not seem like a critical difference, in functional programming this can cause mayhem. Consider the following code snippet:

if (true) {
  function foo(){console.log('one')};
}
else {
  function foo(){console.log('two')};
}
foo();

When the foo() function is called, two is printed to the console, not one!

Finally, there is a way to combine both function expressions and declarations. It works as follows:

var foo = function bar(){ console.log('hi'); };
foo(); // 'hi'
bar(); // Error: bar is not defined

It makes very little sense to use this method because the name used in the declaration (the bar() function in the preceding example) is not available outside the function and causes confusion. It would only be appropriate for recursion, for example:

var foo = function factorial(n) {
  if (n == 0) {
    return 1;
  }
else {
    return n * factorial(n-1);
  }
};
foo(5);

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.3.208