正确使用const来定义函数

在JavaScript中使用const可以设置什么类型的值,特别是函数,有任何限制吗?这有效吗?当然,它确实有效,但出于某种原因,它被认为是一种坏做法吗?

const doSomething = () => {
...
}

在ES6中所有函数都应该这样定义吗?这似乎并没有流行起来,如果是的话。

304810 次浏览

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

函数声明,即:

function doSomething () {}

完全提升到作用域的顶部(像letconst一样,它们也是块作用域)。

这意味着以下将起作用:

doSomething() // works!
function doSomething() {}

一个函数表达式,即:

[const | let | var] = function () {} (or () =>

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

因此,在作用域内提升变量的通常规则——块作用域变量(letconst)不会作为undefined提升到其块作用域的顶部。

这意味着:

if (true) {
doSomething() // will fail
const doSomething = function () {}
}

将失败,因为doSomething未定义。(它将抛出ReferenceError)

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

就标准实践而言,您应该始终使用合适的工具来完成这项工作。

Axel Rauschmayer有一篇关于范围和提升的很棒的文章,包括es6语义:ES6中的变量和作用域

虽然使用const来定义函数看起来像是一种hack,但它带来了一些巨大的优势,使其更优越(在我看来)

  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

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

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

据我所知,它是JavaScript中最具指示性和可预测性的变量声明,也是最有用的变量声明之一,因为它的约束程度很高。为什么?因为它消除了varlet声明的一些可能性。

当你读取const时,你能推断出什么?你只需要阅读const声明语句就可以知道以下所有内容,而不需要扫描对该变量的其他引用:

  • 值被绑定到该变量(尽管它的底层对象不是深度不可变的)
  • 它不能在其直接包含块的外部访问
  • 由于临时死区(TDZ)规则,在声明之前永远不会访问绑定。

以下引文来自一篇文章,论证了letconst的好处。它也更直接地回答了你关于关键字的约束/限制的问题:

诸如letconst所提供的约束是一种使代码更容易理解的强大方式。尝试在您编写的代码中积累尽可能多的这些约束。限制一段代码含义的声明性约束越多,将来人们阅读、解析和理解一段代码就越容易、越快。

当然,const声明比var声明有更多的规则:块作用域,TDZ,在声明时赋值,不重赋。而var语句只表示函数作用域。然而,规则计数并不能提供很多见解。最好从复杂性的角度来衡量这些规则:该规则增加了复杂性还是减少了复杂性?在const的例子中,块作用域意味着比函数作用域更窄,TDZ意味着我们不需要从声明向后扫描作用域,以便在声明之前发现用法,赋值规则意味着绑定将始终保持相同的引用。

语句约束越多,一段代码就越简单。当我们为语句的含义添加约束时,代码变得不那么不可预测了。这就是为什么静态类型的程序通常比动态类型的程序更容易阅读的最大原因之一。静态类型对程序编写者施加了很大的约束,但它也对如何解释程序施加了很大的约束,使其代码更容易理解。

考虑到这些参数,建议在可能的情况下使用const,因为它是让我们考虑的可能性最少的语句。

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

这个问题已经问了三年了,我现在才突然想到。由于这个答案是如此之远,请允许我重复一遍:

问:我感兴趣的是,如果有任何限制什么类型的值可以 在javascript中使用const设置—在特定的函数中。这有效吗? 假定它确实工作,但被认为是任何坏的做法 原因吗?< /强> < / p >

在观察到一个多产的JavaScript程序员总是functions使用const语句后,我被激励去做一些研究,即使没有明显的原因/好处。

在回答“出于某种原因,这被认为是不好的做法吗?”时,让我说,在我看来,是的,或者至少,有优势来使用function语句。

在我看来,这在很大程度上是一个偏好和风格的问题。上面有一些很好的参数,但没有一个像本文中所做的那样清楚:

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

我敦促每个人都读那篇文章,即使你已经做出了决定。

以下是要点:

与[const] Function相比,Function语句有两个明显的优势 表达式:< / h2 >

优点1:意图清晰

扫描时 每天成千上万行的代码,能够弄清楚是很有用的
.
.

优点2:声明的顺序=执行的顺序

理想情况下,我想要声明我的代码或多或少的顺序,我

这是我的showstopper:使用const声明的任何值 关键字在执行到达之前是不可访问的 上面我所描述的迫使我们编写看起来像 颠倒了。我们必须从最低层次的函数开始工作

我的大脑不是那样工作的。我想先了解背景,再了解细节。

大多数代码是由人类编写的。所以大多数人的 理解的顺序大致遵循大多数代码的执行顺序

有一些特殊的情况,arrow functions只是不会做的把戏: .

  1. 如果我们正在改变一个外部API的方法,并且需要对象的引用。

  2. 如果我们需要使用特殊的关键字,这些关键字不属于function表达式:argumentsyieldbind等。 欲了解更多信息: 箭头函数表达式限制 < / p >

例子:

我在Highcharts API中将此函数分配为事件处理程序。 它是由标准库触发的,因此this关键字应该匹配特定的对象
export const handleCrosshairHover = function (proceed, e) {
const axis = this; // axis object
proceed.apply(axis, Array.prototype.slice.call(arguments, 1)); // method arguments
};


对于箭头函数,this将匹配声明作用域,并且我们将无法访问API obj:

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