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
)。
如果您切换为使用var
,则可以获得变量的提升,但它的值将初始化为undefined
,因此仍无法使上面的代码块正常工作(这将抛出一个TypeError
,因为在调用时doSomething
不是函数)。
就标准实践而言,您应该始终使用适当的工具来完成工作。
Axel Rauschmayer在其关于范围和提升的文章中介绍了ES6语义学:Variables and Scoping in ES6
function a(){console.log(this);}
和 b const a=_=>{console.log(this);}
之间的一个微妙区别是,如果您像这样调用它 a.call(someVar);
,在 a 中,它将打印 someVar
,而在 b 中,它将打印 window
。 - user1663023const
定义函数看起来像个技巧,但它具有一些优势,使它在我看来更好:
这使得函数成为不变量,因此您不必担心该函数被其他代码更改。
您可以使用箭头函数语法,这样更短且更清晰。
使用箭头函数会自动处理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
function f(x, y) {
更短,除非你的函数可以成为表达式。 const f = (x, y) => {
是21个字符,比function f(x, y) {
多3个字符。this
的函数内部)定义函数时,保留此绑定才有意义。在顶层脚本中没有意义。function
,但在你的比较中,你忽略了 function
需要 return
,而另一种方法则不需要。(除非我不知道有一个快捷方式?) - ashleedawg这个问题被提出已经三年了,但我现在才遇到它。由于这个回答在堆栈中的位置很靠后,请允许我重复一遍:
问:我想知道在JavaScript中使用const关键字设置值的类型有没有限制,特别是函数。这样做是否有效?尽管它确实起作用,但这是否被认为是不良行为?
在观察到一个热衷于使用const
语句来定义functions
的JavaScript程序员之后,我被激发去做一些研究,即使没有明显的原因/好处。
对于“是否因为任何原因被认为是不良行为?”让我说,我认为,至少在使用function
语句方面有一些优点。
在我看来,这主要是一种偏好和风格的问题。上面提出了一些很好的论点,但没有像这篇文章中那样清晰明了:
Constant confusion: why I still use JavaScript function statements,作者是medium.freecodecamp.org的Bill Sourour,JavaScript大师、咨询师和教师。
我敦促每个人都阅读这篇文章,即使你已经做出了决定。
以下是主要内容:
函数声明相对于 [const] 函数表达式有两个明显的优势:
优势 #1: 明确的意图
在一天扫描数千行代码时,能够尽快轻松地理解程序员的意图非常有用。
优势 #2: 声明顺序 == 执行顺序
理想情况下,我希望以预期执行的顺序更或多或少地声明我的代码。
这对我来说是一个绝妙的问题:使用 const 关键字声明的任何值在执行到它之前都是不可访问的。
我刚才描述的强制我们编写看起来上下颠倒的代码。我们必须从最低层函数开始,并逐步向上工作。
我的大脑不是那样运转的。我希望先了解背景再了解详情。
大多数代码都是由人编写的。因此,按照代码执行的顺序,大多数人的理解顺序大致相同。
defaultErrorHandler
常量,分配为匿名函数,然后我可以从promise处理程序中调用它。这将使我能够根据需要在函数内部可选地“覆盖”此默认错误处理程序。有些只需要返回错误对象,而其他一些则需要返回http响应,不同级别的详细程度。但代码结构可以是熟悉的模式。 - Jake T..then( res.success, res.error )
,比起我之前声明匿名函数来调用res.success(value);
。有一个.then( ..., defaultErrorHandler)
常见模式可能很好,有一个顶层定义的defaultErrorHandler函数,并且可以选择在函数范围内声明一个const defaultErrorHandler = error => { ... }
。 - Jake T.function tomorrow() { }
和 const tomorrow = () => { }
的区别,但这只是习惯于看到其中一种而不是另一种的情况吧?过了一两天后,您应该能够适应发现新模式的能力... 此外,如果您在搜索或正则表达式中需要函数,则将 function
替换为 ) => {
同样好,甚至更好,因为您避免了任何带有 function 一词的注释。 - Jack_Hu使用const
有一些非常重要的好处,有人会说应该尽可能地使用它,因为它是多么明确和指示性。就我所知,在JavaScript中,它是最具指示性和可预测性的变量声明之一,并且也是最有用的之一,因为它非常受限制。为什么呢?因为它消除了var
和let
声明中的一些可能性。
当你读到一个const
时,你可以推断出以下所有内容,而不需要扫描其他对该变量的引用:
以下引用来自一篇文章,主张使用let
和const
的好处。它还更直接地回答了您关于关键字约束/限制的问题:
使用像
let
和const
这样的约束条件是使代码更易于理解的一种强大方式。尽可能在编写代码时积累这些约束条件。限制一段代码可能意味着什么的声明性约束越多,人类在未来阅读、解析和理解代码就会变得越容易和快速。当然,
const
声明比var
声明有更多的规则:块级作用域、TDZ、声明时赋值、不可重新分配。而var
语句只表示函数作用域。然而,计算规则并不能提供太多见解。更好的方法是根据复杂性权衡这些规则:该规则增加还是减少了复杂性?在const
的情况下,块级作用域意味着比函数作用域更窄的范围,TDZ 意味着我们不需要从声明开始向后扫描范围以查找先于声明的使用,并且赋值规则意味着绑定将始终保留相同的引用。语句受到的约束越多,一段代码就变得越简单。随着我们增加对语句可能意味着什么的约束,代码变得更加可预测。这是为什么静态类型程序通常比动态类型程序更易于阅读的最大原因之一。静态类型对程序编写者施加了很大的限制,但它也对程序的解释方式施加了很大的限制,使其代码更易于理解。
考虑到这些论点,建议您在可能的情况下使用
const
,因为它是给我们最少思考可能性的语句。
function
与const
的区别,而不是var
和const
。这个回答本身就表明了在现代Javascript中,使用const
定义一个function
并不能提高可读性,实际上反而会降低可读性。因为这个回答已经将它与变量混淆了起来,而不是函数。 - Elijah Lynn有一些特殊情况,箭头函数
无法解决:
如果我们需要改变外部API的方法并需要对象的引用。
如果我们需要使用仅适用于function
表达式的特殊关键字: arguments
, yield
, bind
等。
欲了解更多信息:
箭头函数表达式的限制
示例:
我将这个函数指定为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对象:
export const handleCrosshairHover = (proceed, e) => {
const axis = this; // this = undefined
proceed.apply(axis, Array.prototype.slice.call(arguments, 1)); // compilation error
};
var doSomething = <function def>;
没有太大的区别。4)“所有函数都应该使用 ES6 中的这种方式定义吗?”对我来说有些复杂。我喜欢函数声明。每个人都有自己的偏好。 - Felix Klingconst
实现什么目的。你想防止自己重写函数吗?我假设您知道您的代码不会这样做。您想表达doSomething
的意图,即它保存一个函数并且不更改其值吗?我认为函数声明也能清晰地表达这个意图。所以,如果你需要在运行时保护代码以防止被覆盖,那就使用const
。否则我看不出有太多好处。当然,如果您主要使用var foo = function() {};
,那么我会使用const
替代var
。 - Felix Klingconst
就没有任何意义了。 - meandreconst
代替function
来定义一个“函数”会降低代码可读性。我在停止4-5年后重新开始使用JS,遇到了一堆用const
声明function
代码,这让我很烦恼。 - Elijah Lynn