Difference Between a Function Expression VS Declaration in JavaScript

Performance difference between function declarations vs function expressions

There is no difference in performance between these two methods.

var myFunc = function(){/*do stuff*/}

or

function myFunc(){/*do stuff*/}

However the first function is created only when the line is executed. But the second function is available even when the script starts to execute.

It is important to understand Javascript Hoisting to explain this behavior.

Here is another useful article on this.

Know JavaScript Function Expression vs Function Declaration, but what is this? Named Function Expression?

What happens to abc?

It contains a function object. If you are doing nothing with it, it will be garbage-collected.

Why it works?

Why not? What "works"?

abc can be called but not def, why?

This is only true from outside, and not in IE. See below.

Is it a function declaration or an expression?

It is a function expression. You can easily see that as it is part of an assignment expression; declarations always need to be on top level (of functions or global code)

def is undefined - why?

Only from outside. A function expression does not create variables. "def" is the name of the function, and inside the function it is a reference to the function as well. This allows recursion for example without using any outer variables.

var abc = function def() {
def === abc; // true
def.name; // "def"
}
abc();
def; // undefined

If it is supposed to be, are there memory leaks?

Yes, in Internet Explorer. It creates two distinct functions from that code. For the details, see http://kangax.github.com/nfe/#jscript-bugs

Why is abc.prototype is function def?

It is not. It is just an object. Maybe it is shown with that name in your console, as belongs to a function named "def".

Why is it called a function expression and not a function declaration?

Interesting question. Wording can have soft boundaries, which is partly what causes this confusion.

First, some rough definitions:

  • Expression: I think this is best thought of with an example. 2 * 2 is an expression, because you can continue doing other operations on it, like 2 * 2 - 3. if (...) on the other hand is not an expression in javascript, it does not resolve into a value in which you can do further operations on. It's invalid to do if (...) {...} / 2. This "definition" has some holes, but should be good enough for the purposes of this answer.
  • Declaration: A declaration is just declaring that you're going to use a certain variable name. So, in your example with const foo = 5, It's the const foo part that actually declares, the = 5 is just initializing the declaration.

With that in mind, lets consider two examples of functions, and see how this terminology plays into these examples:

  1. const g = function() {}

There is a declaration going on here, the const g. We also see that there's a function being created and assigned to g. We're doing something with the result of function() {} (we're assigning it to something), which means javascript will interpret this as a function expression.


  1. function f() {}

We're not using this function as an expression (we're not doing any additional operations with it after we create it), so javascript will actually treat this different from our first example. It's going to declare f in the local namespace, and it's going to apply function hoisting. If you simply added a + before function f() {}, then you would cause javascript to interpret this as an expression instead, and these features will be disabled. You can try it in the dev tools - put in +function f(){} or const g = function f(){}, and f will remain undefined.

The fact that javascript treats the function keyword differently in different contexts is at the heart of this language choice. You can almost think of the "function" keyword as having two different meaning, and the chosen meaning depends on the context. Any time the function is used in an expression context or when it's unnamed, then it takes on the "expression" form, and we call it a "function expression". Otherwise, it takes on the alternative form that contains some extra features, like declaring the function name as a local variable. This is probably why we've adopted to call this alternative form a function declaration. However, like the OP rightly pointed out, even with const f = function() {}, a declaration is still happening, it's just not happening by the function keyword.

Footnote: With examples like +function f() {}, f won't be defined in the same scope as g, but it does get defined inside the body of f. In other words, any named function expression declares its name within its own body.

Function expressions vs function declarations: return value

On the other hand, a function expression does return a value.


This is confusing

Yes indeed. What they actually meant was a function expression evaluates to a (function) value - in contrast to a declaration, which is not an expression but a statement and doesn't evaluate to anything. It has nothing do with the value that the function might return from a call.

Difference between function declaration and function expression in object literal

Actually there is no difference, according to MDN

Starting with ECMAScript 2015, a shorter syntax for method definitions
on objects initializers is introduced. It is a shorthand for a
function assigned to the method's name.

Difference between function expression in global scope and function declaration

When you define a function without using var statement, by default the function will be defined as a property in the global scope.

Quoting MDN documentation on var,

Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed. The differences between declared and undeclared variables are:

  1. Declared variables are constrained in the execution context in which they are declared. Undeclared variables are always global.

  2. Declared variables are created before any code is executed. Undeclared variables do not exist until the code assigning to them is executed.

  3. Declared variables are a non-configurable property of their execution context (function or global). Undeclared variables are configurable (e.g. can be deleted).

Because of these three differences, failure to declare variables will very likely lead to unexpected results. Thus it is recommended to always declare variables, regardless of whether they are in a function or global scope. And in ECMAScript 5 strict mode, assigning to an undeclared variable throws an error.

So, when you define with function function_name(...){...} syntax, it will be in the current scope.

Since the second function definition is in the global scope tr's onclick can find f. Try using var statement like this

var f = function(){
alert('IT WORKS!!');
}

you will get the same ReferenceError: f is not defined.

function declaration and function expression performance difference

With the powerful optimizations JavaScript engines are using these days, Micro-benchmarks like this produce somewhat misleading results. For example, I'm guessing what you were trying to measure is function call overhead. But it looks like the way your code is written, you may be (re)defining the function definition and/or symbol lookup once for every 10 times you execute it; I'm guessing that wasn't the intent.

In this alternative test, I've arranged things to avoid repeated definition of the function, and added a few other ways of invoking the functions. This reduces the difference in performance to something I'd consider dominated by experimental noise. While this there may sometimes be apparent differences but I wouldn't consider them statistically significant given the experimental error levels. In other words, it reduces the contest to a virtual tie.

Even in browsers where there's a consistent difference between approaches, caching the function in a local variable seems to minimize the difference between definition and expression.

Advantages to use function expression instead of function declaration?

Along with that very good answer, the only advantage I can see is dynamically changing a function call.

For example this code :

function foo(){
console.log('foo');
}

function bar(){
console.log('bar');
}

var myFn = foo;

myFn();

setInterval(function(){
if(myFn === foo) myFn = bar;
else myFn = foo;
}, 5000);

setInterval(function(){
myFn()
}, 6000);

It will never log the same thing since you reassign a global variable, every innerscope function will change while this code :

function foo(){
console.log('foo');
}

setInterval(function(){
function foo(){
console.log('Changed foo');
}

foo()
}, 5000)

setInterval(function(){
foo()
}, 5000)

Will log 2 different things. You can only change the current scope function, not the global.



Related Topics



Leave a reply



Submit