正确使用const来定义JavaScript中的函数

Dav*_*air 151 javascript const function ecmascript-6

我感兴趣的是,const在JavaScript中使用特定功能可以设置哪些类型的值有任何限制.这有效吗?虽然它确实有效,但是出于任何原因它被认为是不好的做法?

const doSomething = () => {
   ...
}
Run Code Online (Sandbox Code Playgroud)

是否应该在ES6中以这种方式定义所有功能?如果是这样的话,似乎并没有这样.

谢谢你的评论!

tko*_*one 212

你所做的事情没有问题,但你必须记住函数声明和函数表达式之间的区别.

一个函数声明,即:

function doSomething () {}
Run Code Online (Sandbox Code Playgroud)

完全悬挂在范围的顶部(并且类似let,const它们也是块范围).

这意味着以下内容将起作用:

doSomething() // works!
function doSomething() {}
Run Code Online (Sandbox Code Playgroud)

一个函数表达式,即:

[const | let | var] = function () {} (or () =>
Run Code Online (Sandbox Code Playgroud)

是创建匿名函数(function () {})和创建变量,然后将该匿名函数赋值给该变量.

因此,范围内变量提升的通常规则 - 块范围变量(letconst)不会提升undefined其块范围的顶部.

这意味着:

if (true) {
    doSomething() // will fail
    const doSomething = function () {}
}
Run Code Online (Sandbox Code Playgroud)

将失败,因为doSomething没有定义.(会抛出一个 ReferenceError)

如果你切换到使用var你得到你的变量的提升,但它将被初始化,undefined以便上面的代码块仍然无法正常工作.(这会抛出一个TypeError因为doSomething你在调用它时不是一个函数)

就标准做法而言,您应该始终使用适当的工具来完成工作.

Axel Rauschmayer在范围和悬挂方面有很棒的帖子,包括es6语义:ES6中的变量和范围

  • 只想补充一点,es6类在内部使用const来保护类名不被重新分配. (7认同)
  • ***a*** `function a(){console.log(this);}` 和 ***b*** `const a=_=>{console.log(this);} 之间的一个细微差别` 是如果你像 `a.call(someVar);` 一样调用它,在 ***a*** 中,它会打印 `someVar`,在 ***b*** 中,它会打印 `window`。 (5认同)

Gaa*_*far 77

虽然使用const定义函数看起来像是一个黑客,但它带来了一些很大的优势,使它更优越(在我看来)

  1. 它使函数不可变,因此您不必担心该函数被其他一些代码更改.

  2. 您可以使用胖箭头语法,它更短更清晰.

  3. 使用箭头功能可以this为您进行绑定.

例子 function

// define a function
function add(x, y) { return x + y; }

// use it
console.log(add(1, 2)); // 3

// oops, someone mutated your function
add = function (x, y) { return x - y; };

// now this is not what you expected
console.log(add(1, 2)); // -1
Run Code Online (Sandbox Code Playgroud)

同样的例子 const

// define a function (wow! that is 8 chars shorter)
const add = (x, y) => x + y;

// use it
console.log(add(1, 2)); // 3

// someone tries to mutate the function
add = (x, y) => x - y; // Uncaught TypeError: Assignment to constant variable.
// the intruder fails and your function remains unchanged
Run Code Online (Sandbox Code Playgroud)

  • 1.不变性是一个真正的好处,但实际上覆盖一个函数是非常罕见的.2.胖箭头语法不会更短,除非你的函数可以是一个表达式.`function f(x,y){`是18个字符,`const f =(x,y)=> {`是21个字符,所以3个字符更长.3.只有在方法(或其他有意义的函数)中定义函数时,保持此绑定才有意义.在顶级脚本中它是毫无意义的.我并不是说你错了,只是你提到的原因并不十分重要. (20认同)
  • 我会使用 linter 来防止重新绑定函数声明。 (7认同)
  • 老式函数语法的一个优点是在调试过程中有一个名称。 (6认同)
  • “您可以使用粗箭头语法,它更短、更清晰。” - 有时,如果代码更短、更简洁,那么它会让其他开发人员更难理解,那么这并不是更好。好的编程不仅仅是编写有效的简短代码,还包括编写可维护的代码。 (5认同)
  • @Nakedible - 我也更喜欢使用“function”,但在您的比较中,您忘记了“function”需要“return”,而其他方法则不需要。(除非我不知道有捷径?) (2认同)

JMi*_*lTX 17

问这个问题已经三年了,但我现在才碰面.由于这个答案到目前为止,请允许我重复一遍:

问:我感兴趣的是,在JavaScript中使用const设置哪些类型的值有任何限制 - 特别是函数.这有效吗?虽然它确实有效,但是出于任何原因它被认为是不好的做法?

在观察了一个总是使用const语句的多产JavaScript编码器之后functions,即使没有明显的理由/好处,我也有动力做一些研究.

回答" 因为任何原因它被认为是不好的做法吗? "让我说,IMO,是的,或者至少,使用声明是有好处的function.

在我看来,这在很大程度上取决于偏好和风格.上面有提出了一些很好的理由,但没有那么清楚这篇文章中做:

恒困惑:为什么我仍然可以使用JavaScript函数语句由medium.freecodecamp.org/Bill Sourour,JavaScript的大师,顾问和教师.

即使你已经做出决定,我也敦促大家阅读那篇文章.

以下是要点:

与[const]函数表达式相比,函数语句有两个明显的优点:

优势#1:意图的清晰度

每天扫描数千行代码时,能够尽可能快速,轻松地找出程序员的意图是很有用的.

优势#2:声明顺序==执行顺序

理想情况下,我想按照我希望它将被执行的顺序或多或少地声明我的代码.

这对我来说是showstopper:使用const关键字声明的任何值在执行到达之前都是不可访问的.

我刚才描述的内容迫使我们编写颠倒的代码.我们必须从最低级别的功能开始,然后继续努力.

我的大脑不会那样工作.我想在细节之前的上下文.

大多数代码都是由人类编写的.因此,大多数人的理解顺序大致遵循大多数代码的执行顺序是有道理的.

  • @杰克T。RE“您能否对意图的清晰度稍加评论?”。嗯,首先,那句话不是我写的,而是那篇文章的作者 freecodecamp.org/Bill Sourour 写的。但这对我来说是真正的常识。如果我读到“函数明天()”,那么我立即知道它是一个函数。但是如果我读到“const today = () =>”,我会停下来解析我脑海中的语法,最终确定,好吧,是的,它是一个函数。 (2认同)

小智 10

有些特殊情况是arrow functions无法解决问题的:

  1. 如果我们要更改外部 API 的方法,并且需要对象的引用。

  2. 如果我们需要使用表达式独有的特殊关键字functionargumentsyieldbind。更多信息: 箭头函数表达式限制

例子:

我将此函数指定为 API 中的事件处理程序Highcharts。它是由库触发的,因此this关键字应该与特定对象匹配。

export const handleCrosshairHover = function (proceed, e) {
  const axis = this; // axis object
  proceed.apply(axis, Array.prototype.slice.call(arguments, 1)); // method arguments
};

Run Code Online (Sandbox Code Playgroud)

使用箭头函数,this将匹配声明范围,并且我们将无法访问 API 对象:

export const handleCrosshairHover = (proceed, e) => {
  const axis = this; // this = undefined
  proceed.apply(axis, Array.prototype.slice.call(arguments, 1)); // compilation error
};

Run Code Online (Sandbox Code Playgroud)


小智 8

使用有一些非常重要的好处const,有些人会说它应该尽可能地使用,因为它是多么刻意和指示性.

据我所知,它是JavaScript中最具指示性和可预测性的变量声明,也是最有用的变量之一,因为它有多么受限制.为什么?因为它消除了可用varlet声明的一些可能性.

你读什么时可以推断出什么const?只需通过读取const声明语句就可以了解以下所有内容,并且不扫描对该变量的其他引用:

  • 该值绑定到该变量(尽管其底层对象不是非常不可变的)
  • 它不能在其包含的块之外访问
  • 由于时间死区(TDZ)规则,在声明之前永远不会访问绑定.

以下引用来自一篇论述let和的好处的文章const.它还更直接地回答了关于关键字约束/限制的问题:

诸如由提供者提供的约束let以及const使代码更易于理解的强大方法.尝试在您编写的代码中尽可能多地产生这些约束.限制代码片段可能意味着什么的声明性约束越多,人类在将来阅读,解析和理解一段代码就越容易和快捷.

当然,const声明的规则多于声明的规则var:块范围,TDZ,声明时分配,不重新分配.而var陈述仅表示功能范围.然而,规则计算并没有提供很多见解.最好在复杂性方面权衡这些规则:规则是增加还是减少复杂性?在这种情况下const,块作用域意味着比函数作用域更窄的范围,TDZ意味着我们不需要从声明向后扫描作用域以便在声明之前发现使用,并且赋值规则意味着绑定将始终保留相同的参考.

约束语句越多,一段代码就越简单.当我们为语句的含义添加约束时,代码变得不那么难以预测.这是静态类型程序通常比动态类型程序更容易阅读的最大原因之一.静态类型给程序编写器带来了很大的限制,但它也对程序的解释方式提出了很大的限制,使代码更容易理解.

考虑到这些论点,建议您const尽可能使用,因为这是使我们思考的可能性最小的陈述.

资料来源:https://ponyfoo.com/articles/var-let-const

  • 这个问题是关于“function”与“const”,而不是“var”与“const”。这个答案本身就表明,使用 const 来定义 function 并不是可读性的增强,实际上是现代 JS 中可读性的回归。因为这个答案已经将其混淆为变量,而不是函数。 (14认同)