在Javascript中,什么时候需要为一个变量分配一个命名函数? [英] In Javascript, when is it necessary to assign a named function to a variable?

查看:98
本文介绍了在Javascript中,什么时候需要为一个变量分配一个命名函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Babel JS的在线REPL( http://babeljs.io/repl/ )中,当我输入:

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

let a = (x) => x+1

它将被转载到:

"use strict";

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

这里 var a = function a(x)看起来有点令我困惑,因为 var a = function(x)函数a(x)是否足够我了解。

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.

有没有人有关于何时以及为什么需要为变量分配一个命名函数的想法? p>

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

推荐答案

这里有两个不同的问题:

There are really two different questions here:



  1. 为什么 let a =(x)=> x + 1 以这种方式被转载?

  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?

为了回答(2)我们需要了解( 1) - 已在SO和其他地方广泛讨论。我们来看看你提到的三种方法:

In order to answer (2) we need to understand (1)-- which has been extensively discussed on SO and elsewhere. Let's go through the three alternatives you mentioned:

函数声明

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.

(匿名)函数表达式

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

var a 本身将在解析时被挂起,但它将是 undefined

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

命名函数表达式

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; }



匿名)将导致错误。

应该直观地清楚为什么 let a =(x )=> x + 1 should not 被转换为函数声明。我们分配箭头函数(x)=> x + 1 到具有 let 的块范围变量,所以我们应该期望 a

It should be intuitively clear why let a = (x) => x + 1 should not be transpiled to a function declaration. 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.

所以,我们有一个问题:为什么 let a =(x)=> x + 1 被转换为命名函数表达式而不是匿名函数表达式?有什么不同?正如Alnitak和其他人所指出的那样:

So, we have one question left: 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:


  • 函数名称出现在调试器中,这可能是有用的。

  • 一个命名函数定义的范围内有对函数本身的引用。这允许递归和访问包含函数的属性。

所以命名函数表达式有一些不错的属性那个匿名函数表达式不要。但实际上似乎在这里应该会发生什么分歧。根据 MDN

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

这个答案为什么使用命名函数表达式?说:


[从ES6开始]很多匿名函数表达式使用名称创建函数,而这是由各种现代JavaScript引擎推测出来的,它们相当于从语境中推断出名称。这些引用遍布整个规范

"[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"

其他参考资料:

  • var functionName = function() {} vs function functionName() {}
  • Javascript - Precedence in hoisting

我发现最好的办法就是使用 Babel REPL 进行处理。

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

这篇关于在Javascript中,什么时候需要为一个变量分配一个命名函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆