What are the advantages of function expressions?

So does someone have an example of why I’d ever want to use a function expression over a function declaration?

55 Likes

I’m a little confused as to the application for Function Expressions, at least in the way it’s being shown in the exercise and my current understanding.

At a glance it appears redundant to declare a variable to hold a function when a function can just be declared on it’s own. Is it maybe related to memory usage throughout a larger program?

I think an example of a practical use case would set me straight.

Insight would be appreciated.
Thanks!

18 Likes

This is an article from 2015, before arrow functions were adopted into regular use, but it can apply to them, as well, for the most part.

Quick Tip: Function Expressions vs Function Declarations

Conslusion
As we’ve seen, function expressions don’t offer much that can’t be achieved with function declarations, but using them can often result in cleaner and more readable code. Their widespread use makes them an essential part of every developer’s toolbox.

110 Likes

you can see here :

at the part called function hoisting.

Then at this part of lesson from codecademy
https://www.codecademy.com/courses/introduction-to-javascript/lessons/functions/exercises/function-expressions?action=resume_content_item

it said :

Unlike function declarations, function expressions are not hoisted so they cannot be called before they are defined.

for me that is the advantage from function expressions.

26 Likes

You can also assign an anonymous function to be the value of a variable, for example:

const myGreeting = function() {
  alert('hello');
}

This function could now be invoked using:

myGreeting();

This effectively gives the function a name; you can also assign the function to be the value of multiple variables, for example:

let anotherGreeting = myGreeting;

This function could now be invoked using either of:

myGreeting();
anotherGreeting();

But this would just be confusing, so don’t do it! When creating functions, it is better to just stick to this form:

function myGreeting() {
  alert('hello');
}

You will mainly use anonymous functions to just run a load of code in response to an event firing — like a button being clicked — using an event handler. Again, this looks something like this:

myButton.onclick = function() {
  alert('hello');
  // I can put as much code
  // inside here as I want
}
46 Likes

In advanced programming, you might want to write functions that take in other functions as arguments. For example, you might want a function applyTwice(f, x) which applies the function f on x twice. If you want to call this function, you probably need a function expression for the first argument.

13 Likes

Well i guess it removes the need of using the variable in front of it like instead of function water(amount){}; it instead changes to const water = function(amount) thereby removing the water in front of the amount but its pretty useless

1 Like

Notwithstanding what hoisting offers, there is no defense for a declared function. It can be deleted. I see no advantage in this respect to using function declarations, at all.

Know how functions work and go from there. Production settings are always going to dictate. const is the way to protect assigned function expressions.

const foo = x => x ** 2
2 Likes

I don’t really see the point of function expressions I’ll learn about them and just move on and probably never use them. :sweat_smile:

I thought maybe you could assign a value to a variable at runtime and then refer to that later on, but that doesn’t seem possible at first observation.

For example in Scala, you could write:

val fruit = dayOfWeek match {
  case 'Monday' => 'Apple'
  case 'Tuesday' => 'Pear'
}

Which pending on the value of dayOfWeek would define what the variable fruit is. Is something like this possible in JS? I’m just trying to see the benefits of function expressions. They just seem to have replaced the keyword function with const

Can arrow functions be used with standard functions or only with function expressions?

1 Like

Not so. const and let are declaration keywords that redefine var to a tighter scope reference. The function keyword is not replaced.

const fruit = function (day) {
  switch (day) {
  case 'Monday': return 'Apple';
  case 'Tuesday': return 'Pear';
  // ...
  default: return 'Error'
  }
}
console.log(fruit('Tuesday'))    // Pear

Arrow functions have replaced the function keyword with a fat arrow. It is also written after the parameter list instead of before.

const fruit = (day) => {
  switch (day) {
    case 'Monday': return 'Apple';
    case 'Tuesday': return 'Pear';
    // ...
    default: return 'Error'
  }
}

At the very heart of programming are functions. There is no getting around them, and it is not possible to, ‘just move on.’

The function declaration is the most fundamental, but it has a weakness. It can be deleted or replaced.

function foo (param) {
    // code
    return value
}

A function expression can take two forms. The ES5 form,

var foo = function (param) {
    // code
    return value
}

and the new ES6 form,

const foo = (param) => {
    // code
    return value
}

The above ES5 form is just as vulnerable as the declaration form. We can now protect it the same as the above arrow function, with const.

const foo = function (param) {
    // code
    return value
}

We can still use this form of function expression as a constructor, which will come up later in the course. It has all the properties of a declared function so is not very different at all, save that we can now protect it.

Arrow functions for all their simplicity have those properties stripped away. They have no arguments object, no this property and cannot be used as constructors. But, they also have relaxed syntax rules for simple, pure functions with a single parameter and single return expression…

const foo = param => expression;

At any length, you will never escape the need for or use of functions in whatever form. Without them expect your code to be very spaghettified, difficult to debug, error prone and repetitive. Don’t move forward until you are comfortable with and understand how to write and use functions.

16 Likes

so instead of adding variables each time after declaring the function ,we can merge them in one declaration? is this the use of function expression?

It’s called an expression because it can be assigned the same as any value. The function is anonymous (has no name) but we can invoke it with the variable name we assigned it to.

x => x ** 2

As it stands we cannot execute the above expression. However if we assign it to a variable,

y = x => x ** 2

then we can give a value for x and it will return the square of that value.

console.log(y(5))    //  25

What’s more, we can pass that function expression to another function, but that will come up later in the course so I won’t go there now.

Now that y is defined as a function we can invoke it as long as it is in memory.

console.log(y(6))    //  36

console.log(y(13))   //  169
4 Likes

After saying the above myself, that’s all I use now :sweat_smile:

I figured I might as well learn how to do things the current way and just stick with that and arrow functions are handy.

The only confusion I get from time to time is that the const keyword is used for so many things, from a function to an object and a variable.

1 Like

Bottom line, scoping is the most sure-fired way to protect global scope from being polluted, and keep variable nestled away and out of the foray. Whether we use var, let or const depends on where we want the scope to apply, and whether we want variables to be protected or not.

const seems to be used a lot. It tells readers that this variable is constant, and only ever has one value. If we want to be able to change that value at some point, then use let for block scope or var for function scope.

2 Likes

Is a function getting deleted or modified really a big problem in JavaScript? Are we talking multiple coders working on the same code and clashing with each other, or is there some outside factor that makes it a consideration (like maybe your JavaScript program might have to interact with someone else’s program while out on the web – maybe your code is a plugin for wordpress)?

I don’t remember seeing anything to prevent functions from being modified when I was taking the Python 2 course, and a quick google seems to show that you can overwrite a Python function by just defining it again, so not all coding languages appear to care about locking functions down.

Since we don’t have to take any extra measures, declaring a const and assigning a function just makes good sense, to me anyway. JS has only one namespace (although modules might have their own, needs looking into) so the potential for collision with a plug-in is present. I’m not an expert on that, though. If our script is already loaded and a plug-in tries to declare a variable that we have written as a constant, it will throw an error. If we only write it as a declared function, the plug-in could overwrite it with no error thrown, so nobody would be the wiser.

6 Likes

Thanks – it sounds like it would make sense to get in the habit of creating a function by declaring it a constant. I suppose if it saves even one headache, it’s worth making the habit.

1 Like

From what I understood, function expressions are mostly used to prevent modifying the bind between the variable and the function expression. However, as functions are objects, they can be mutated

const foo = function() {
  return "foo";
}

console.log(foo()); // "foo"

foo.bar = 2;

foo.bar; // 2

foo = [1, 2, 3]; // TypeError: Assignment to constant variable

Another reason to use function expressions is scope. Function declaration are function scoped while function expressions are scoped depending on the keyword used to declare the variable - const and let: block scoped. var: function scoped

As functions go, undeclared variables automatically get hoisted to the top of global scope. Declaring variables within the function gives them function scope. Block scope still applies since the function body is still a block. However we’re more concerned about leakage from blocks within a given scope. let and const give block scope to loops, switches, if statements, etc., anything with a block will contain its variables and they will not be accessible outside of that block.

1 Like

I’m sorry, I didn’t really understand what you are trying to say. Are you explaining that variables declared with const and let are block scoped, and undeclared variables are global scoped (no matter how deeply nested they are)? What did you mean by

Are these just examples of blocks?