5

In a Udacity lesson the difference between function expressions and declarations is explained as follows:

A function declaration defines a function and does not require a variable to be assigned to it. It simply declares a function, and doesn't itself return a value ... On the other hand, a function expression does return a value.

This is confusing; to my knowledge, when both function expressions and function declarations include a return statement, both return a value.

If I understand correctly, the difference with respect to return value is that in a function expression, if a value is changed in the first call of the function, in a subsequent call the updated value would be preserved—whereas if the function were not stored in a variable, the return value would be erased when the function is finished executing. Am I missing something, and is the statement from the lesson accurate?

Note: My question is different from the one marked as a duplicate. In that question it asks what the reasons for using one over the other, but return value is not mentioned in the question or explained in its answers.

Deja
  • 3,278
  • 2
  • 18
  • 46
  • 2
    It's a bit confusing, but they aren't talking about what the function itself is returning. They are talking about the difference between `function a() {}` and `function() {}`. The former cannot be assigned to a variable, whereas the latter can. `const a = function a() {}` doesn't work but you could do `const a = function() {}`. Now the constant `a` will be the function itself so you could call it with `a()`. – Jordan Soltman Jun 16 '18 at 20:24
  • 2
    Possible duplicate of [var functionName = function() {} vs function functionName() {}](https://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname) – ChiefTwoPencils Jun 16 '18 at 20:29
  • 2
    @JordanS - I'm confused why you said "const a = function a() {} doesn't work." A function expression can have a name (though it's optional). What am I missing? – Deja Jun 21 '18 at 05:01

5 Answers5

2

The definition isn't talking about the function returning a value, it is talking on how one way of creating a function returns a value (which is the function expression) and another just declares a function (a function declaration).

To help you clarify things, you should understand first what an expression is:

An expression is any valid unit of code that resolves to a value.

One example of an expression would be x = 5, which evaluates to 5. Another example would be 3 + 2, which also evaluates to 5.

In other words, we could say that both expressions above return a value of 5.

A function expression is just an expression that returns (evaluates to) a function:

// expression
const whatever = function expression() {}
//               ^^^^^^^^^^^^^^^^^^^^^^^^ this is the function expression in an assignment statement

A function declaration is not an expression but a statement. It doesn't need to evaluate to a value. It is just immediately declared:

// declaration
function example() {}

How a function is created (via a declaration or an expression) doesn't affect what the function can return - that capability is the same in both cases.

nem035
  • 31,501
  • 5
  • 73
  • 88
2

To understand what this really is about, we need to dig into the JavaScript grammar:

In ECMAScript a script consists of Statements and Declarations. A Statement can be (amongst others) an ExpressionStatement. Note that ExpressionStatement is explicitly defined as:

ExpressionStatement[Yield, Await]:

[lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]

Expression[+In, ?Yield, ?Await];

This looks really cumbersome, but what it says is that an ExpressionStatement cannot possibly start with the keyword function. So if you just write:

function a() {}

This can never be interpreted as an expression although in other circumstances like

const a = function a() {}

it is an expression. (The right hand side of an assignment operation always must be an expression.)

Now, only expressions evaluate a value, statements do not. This is all the text you quote is saying in a hard to understand way.

A function declaration defines a function and does not require a variable to be assigned to it:

True but redundant. A declaration cannot occur at the right hand-side of an assignment.

It simply declares a function, and doesn't itself return a value ...

Yeah, statements do not evaluate to ("return") a value.

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

Sure, like any expression.


See https://www.ecma-international.org/ecma-262/8.0/#prod-StatementList

idmean
  • 13,418
  • 7
  • 47
  • 78
1

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.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
0

You are right to say that example is confusing.

Maybe it helps if you think of "return value" in the context of an interpreter? By that I mean, imagine if you were parsing Javascript yourself (as if you were Chrome's v8).

The declaration would just define a new function type and it'd be available for use after declaration.

// declare a function named Declaration
function Declaration() { // stuff }

Now imagine it is instead an expression getting evaluated.

// named function expression
var foo = function FooFunc() { // do stuff }

// anonymous function expression
var foo = function () { // do stuff }

// a self-invoking anonymous function expression (example of a non-variable assingment
// The parentheses make it self-invoking and not a declaration.
(function foo() { console.log('foo'); })() // outputs 'foo' when parsed
+function foo() { console.log('foo'); }(); // same as above
!function foo() { console.log('foo'); }(); // same as above
-function foo() { console.log('foo'); }(); // same as above
~function foo() { console.log('foo'); }(); // same as above

First, sees if an assignment (or self-execution) is going to take place. Do this by checking for const or var or (.

Let's suppose the expression is the variable assignment var foo = function fooFunc() {}.

In this case, the interpreter knows that while you'r defining fooFunc, you also want the result of the definition -- the fooFunc function -- to be the value of foo and so there is a "return value" -- the fooFunc function object -- that needs to be assigned.

Philip Ramirez
  • 2,822
  • 1
  • 13
  • 16
0

This can be difficult to learn at first, but lets try a different approach.

They are not talking about the returned value of a function call, its about the value of the expression (as well explained in the other answers).

You can use the console in the Chrome's Developer Tools to see what each expreassion evaluates to, for example: if you input 10 in the console, this expression will return 10

> 10
< 10

And so on...

> 10 + 5
< 15

> 'Hello world!'
< "Hello world!"

Assigning a value to an variable (not with var, const or let) returns the variable new value, so you can see this in the console:

> n = 10
< 10

> var foo = (n = 10) // also `var foo = n = 10` or `foo = n = 10`
< undefined

> foo
< 10

> n
< 10

> (obj = {}).foo = 'bar'
< "bar"

> obj
< {foo: "bar"}

When we are talking about functions, the declaration of it does not return any value, but a function expression returns a reference to the function created, thats why you can assign it to a variable.

> function foo() { }
< undefined

> (function() { })
< ƒ () { }

Thats why you can do things like:

> (function() { return 'it works!' })()
< "it works!"

> myFunc = function() { return 'also works!' }
< ƒ () { return 'also works!' }

> myFunc()
< "also works!"

Hope this help you undertand. :)

Alyson Maia
  • 678
  • 4
  • 12