草庐IT

javascript - 在 Javascript 中,什么时候需要将命名函数分配给变量?

coder 2024-07-15 原文

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

let a = (x) => x+1

它将被转译为:

"use strict";

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

这里的 var a = function a(x) 对我来说有点困惑,因为 var a = function(x)function a( x) 据我了解就足够了。

有没有人知道何时以及为什么需要将命名函数分配给变量?

最佳答案

这里确实有两个不同的问题:

  1. 定义或表达函数的不同方式有何区别?
  2. 为什么 let a = (x) => x + 1 以这种方式转译?

为了回答 (2),我们需要理解 (1)-- 这已在 SO 和其他地方进行了广泛讨论。


问题一

让我们来看看您提到的三种选择:

函数声明:

function a(x) { ... }

从语法上讲,这些必须总是function ( reference ) 开头。它们在解析时被提升并在本地范围内创建命名函数。

(匿名)函数表达式:

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

var a 本身将在解析时被提升,但在运行时执行此行之前它将是 undefined

命名函数表达式:

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

尽管语法使它看起来像是对函数声明 的赋值,但这实际上只是一个带有名称的函数表达式。我觉得这令人困惑,但这就是语法。

最大的区别在于函数声明函数表达式。通过声明,您可以:

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

尽管尝试使用函数表达式(命名匿名)会导致错误。


问题2

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

我们将箭头函数 (x) => x + 1 分配给带有 let 的 block 范围变量,所以我们应该期望 a 直到该行在运行时执行后才被定义。这应该是一个函数表达式,而不是一个函数声明

最后,为什么 let a = (x) => x + 1 被转译成一个命名函数表达式而不是一个匿名函数表达式?有什么不同?正如 Alnitak 和其他人所指出的:

  • 函数名称出现在调试器中,这很有用。
  • 命名函数定义内的作用域引用了函数本身。这允许递归和访问包含函数的属性。

因此,命名函数表达式 具有一些匿名函数表达式 所没有的优良特性。但实际上似乎对这里应该发生的事情存在分歧。根据MDN :

Arrow functions are always anonymous

鉴于this answerWhy use named function expressions?说:

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

其他引用:

我发现解决这个问题的最佳方法是使用 Babel REPL .

关于javascript - 在 Javascript 中,什么时候需要将命名函数分配给变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33627048/

有关javascript - 在 Javascript 中,什么时候需要将命名函数分配给变量?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  3. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  7. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  8. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  9. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  10. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

随机推荐