const
在 JavaScript 中可以设置哪些类型的值,尤其是函数,是否有任何限制?这是有效的吗?当然它确实有效,但是出于任何原因它被认为是不好的做法吗?
const doSomething = () => {
...
}
ES6 中的所有函数都应该这样定义吗?如果是这样的话,这似乎并没有流行起来。
const
在 JavaScript 中可以设置哪些类型的值,尤其是函数,是否有任何限制?这是有效的吗?当然它确实有效,但是出于任何原因它被认为是不好的做法吗?
const doSomething = () => {
...
}
ES6 中的所有函数都应该这样定义吗?如果是这样的话,这似乎并没有流行起来。
你所做的没有问题,但你必须记住函数声明和函数表达式之间的区别。
一个函数声明,即:
function doSomething () {}
完全提升到作用域的顶部(let
并且const
它们也是块作用域)。
这意味着以下内容将起作用:
doSomething() // works!
function doSomething() {}
一个函数表达式,即:
[const | let | var] = function () {} (or () =>
就是创建一个匿名函数(function () {}
)和创建一个变量,然后将该匿名函数赋值给那个变量。
因此,在作用域内提升变量的通常规则——块作用域变量(let
和const
)不会提升undefined
到它们的块作用域的顶部。
这意味着:
if (true) {
doSomething() // will fail
const doSomething = function () {}
}
将失败,因为doSomething
未定义。(它会抛出一个 ReferenceError
)
如果您切换到 using,var
您会得到变量的提升,但它会被初始化为undefined
这样,上面的代码块仍然无法工作。(这将抛出一个TypeError
因为doSomething
在您调用它时不是函数)
就标准做法而言,您应该始终使用适合工作的工具。
Axel Rauschmayer 发表了一篇关于作用域和提升(包括 es6 语义)的精彩博文:ES6 中的变量和作用域
虽然使用const
来定义函数看起来像一个黑客,但它有一些很大的优势,使它更胜一筹(在我看来)
它使函数不可变,因此您不必担心该函数会被其他一些代码更改。
您可以使用更短更简洁的粗箭头语法。
使用箭头函数负责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
问这个问题已经三年了,但我现在才遇到它。由于这个答案在堆栈中太远了,请允许我重复一遍:
问:我感兴趣的是,对于在 JavaScript 中使用 const 设置的值的类型是否有任何限制——特别是函数。这是有效的吗?当然它确实有效,但是出于任何原因它被认为是不好的做法吗?
在观察了一位多产的 JavaScript 编码员后,我有动力去做一些研究,他总是使用const
语句 for functions
,即使没有明显的原因/好处。
回答“是否出于任何原因被认为是不好的做法? ”让我说,IMO,是的,或者至少,使用语句有优势function
。
在我看来,这主要是偏好和风格的问题。上面提出了一些很好的论据,但没有像本文中所做的那样清楚:
持续困惑:为什么我仍然使用 JavaScript 函数语句由 medium.freecodecamp.org/Bill Sourour,JavaScript 大师、顾问和教师撰写。
我敦促每个人都阅读那篇文章,即使你已经做出了决定。
以下是要点:
与 [const] 函数表达式相比,函数语句有两个明显的优势:
优势一:意图清晰
每天扫描数千行代码时,能够尽可能快速、轻松地找出程序员的意图非常有用。
优势#2:声明顺序==执行顺序
理想情况下,我想或多或少地按照我预期的执行顺序来声明我的代码。
这对我来说是最重要的:任何使用 const 关键字声明的值在执行到达之前都是不可访问的。
我刚刚在上面描述的内容迫使我们编写看起来颠倒的代码。我们必须从最低级别的功能开始,然后逐步向上。
我的大脑不是那样工作的。我想要细节之前的上下文。
大多数代码是由人类编写的。因此,大多数人的理解顺序大致遵循大多数代码的执行顺序是有道理的。
使用 有一些非常重要的好处const
,有些人会说应该尽可能使用它,因为它是多么深思熟虑和指示性。
据我所知,它是 JavaScript 中最具指示性和可预测性的变量声明,也是最有用的声明之一,因为它是多么受约束。为什么?因为它消除了一些可用于var
和let
声明的可能性。
当你阅读 a 时,你能推断出什么const
?您只需阅读const
声明语句即可了解以下所有内容,并且无需扫描对该变量的其他引用:
以下报价是从一篇文章争论的好处let
和const
。它还更直接地回答了您关于关键字约束/限制的问题:
诸如由
let
和提供的约束const
是使代码更易于理解的强大方式。尝试在您编写的代码中尽可能多地增加这些约束。限制一段代码含义的声明性约束越多,未来人类阅读、解析和理解一段代码就越容易、越快。诚然,
const
声明比声明有更多规则var
:块范围、TDZ、声明时分配、无重新分配。而var
语句仅表示函数作用域。然而,规则计数并没有提供很多洞察力。最好根据复杂性权衡这些规则:规则是增加还是减少复杂性?在这种情况下const
,块作用域意味着比函数作用域更窄的作用域,TDZ 意味着我们不需要从声明向后扫描作用域以便在声明之前发现用法,并且赋值规则意味着绑定将始终保留相同的参考。约束语句越多,一段代码就越简单。当我们为语句的含义添加约束时,代码变得不那么不可预测了。这是静态类型程序通常比动态类型程序更易于阅读的最大原因之一。静态类型对程序编写者施加了很大的约束,但它也对程序的解释方式施加了很大的约束,使其代码更易于理解。
考虑到这些论点,建议您
const
在可能的情况下使用,因为这是让我们考虑的可能性最小的陈述。
有一些特殊情况arrow functions
不会成功:
如果我们正在更改外部 API 的方法,并且需要对象的引用。
如果我们需要使用的是专用的特殊的关键字function
表达式:arguments
,yield
,bind
等欲了解更多信息:
Arrow功能表达的局限性
例子:
我将此函数指定为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
};