Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
336 views
in Technique[技术] by (71.8m points)

ecmascript 6 - In Javascript, when is it necessary to assign a named function to a variable?

In the online REPL of Babel JS (http://babeljs.io/repl/), when I type in :

let a = (x) => x+1

It will be transpiled to:

"use strict";

var a = function a(x) {
  return x + 1;
};

Here the var a = function a(x) looks a bit confusing to me, because either var a = function(x) or function a(x) is enough as I understand.

Does anyone have ideas about when and why it is necessary to assign a named function to a variable?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are really two different questions here:

  1. What are the differences between the different ways of defining or expressing functions?
  2. Why does let a = (x) => x + 1 get transpiled this way?

In order to answer (2) we need to understand (1)-- which has been extensively discussed on SO and elsewhere.


Question 1

Let's go through the three alternatives you mentioned:

Function declaration:

function a(x) { ... }

Syntactically, these must always begin with function (reference). They are hoisted at parse time and create a named function in the local scope.

(Anonymous) Function expression:

var a = function (x) { ... }

var a itself will be hoisted at parse time, but it will be undefined until this line is executed at runtime.

Named Function expression:

var a = function a(x) { ... }

Though the syntax makes it looks like an assignment to a function declaration, this is actually just a function expression with a name. I find this confusing, but that's the syntax.

The big difference is between function declarations and function expressions. With a declaration, you can do:

a(1);
function a(x) { return x + 1; }

though attempting this with a function expression (named or anonymous) will cause an error.


Question 2

  1. Why does let a = (x) => x + 1 get transpiled this way?

We're assigning the arrow function (x) => x + 1 to a block-scoped variable with let, so we should expect that a is not defined until after this line has been executed at runtime. This should be a function expression, not a function declaration.

Last, why is let a = (x) => x + 1 transpiled to a named function expression rather than a anonymous function expression? What's the difference? As Alnitak and others have pointed out:

  • Function names appear in debuggers, which can be helpful.
  • The scope inside of a named function definition has a reference to the function itself. This allows for recursion and accessing properties of the containing function.

So named function expressions have some nice properties that anonymous function expressions don't. But there actually seems to be disagreement on what should happen here. According to MDN:

Arrow functions are always anonymous

whereas this answer to Why use named function expressions? says:

"[As of ES6] a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context... This is strewn throughout the spec"

Other references:

I've found that the best way to get a handle on this is playing around with the Babel REPL.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...