正确使用 const 在 JavaScript 中定义函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33040703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Proper use of const for defining functions in JavaScript
提问by David Sinclair
I am interested if there are any limits to what types of values can be set using const
in JavaScript—in particular functions. Is this valid? Granted it does work, but is it considered bad practice for any reason?
我很感兴趣,是否对const
在 JavaScript 中可以设置的值类型有任何限制——特别是函数。这是有效的吗?授予它确实有效,但是出于任何原因它被认为是不好的做法吗?
const doSomething = () => {
...
}
Should all functions be defined this way in ES6? It does not seem like this has caught on, if so.
在 ES6 中所有的函数都应该这样定义吗?如果是这样的话,这似乎并没有流行起来。
Thanks for any comments!
感谢您的任何评论!
回答by tkone
There's no problem with what you've done, but you must remember the difference between function declarations and function expressions.
你所做的没有问题,但你必须记住函数声明和函数表达式之间的区别。
A function declaration, that is:
一个函数声明,即:
function doSomething () {}
Is hoisted entirely to the top of the scope (and like let
and const
they are block scoped as well).
完全提升到作用域的顶部(let
并且const
它们也是块作用域)。
This means that the following will work:
这意味着以下将起作用:
doSomething() // works!
function doSomething() {}
A function expression, that is:
一个函数表达式,即:
[const | let | var] = function () {} (or () =>
Is the creation of an anonymous function (function () {}
) and the creation of a variable, and then the assignment of that anonymous function to that variable.
是创建一个匿名函数(function () {}
)和创建一个变量,然后将该匿名函数赋值给该变量。
So the usual rules around variable hoisting within a scope -- block-scoped variables (let
and const
) do not hoist as undefined
to the top of their block scope.
因此,在作用域内提升变量的通常规则——块作用域变量(let
和const
)不会提升undefined
到它们的块作用域的顶部。
This means:
这意味着:
if (true) {
doSomething() // will fail
const doSomething = function () {}
}
Will fail since doSomething
is not defined. (It will throw a ReferenceError
)
由于doSomething
未定义,将失败。(它会抛出一个 ReferenceError
)
If you switch to using var
you get your hoisting of the variable, but it will be initialized to undefined
so that block of code above will still not work. (This will throw a TypeError
since doSomething
is not a function at the time you call it)
如果您切换到 using,var
您会得到变量的提升,但它会被初始化为undefined
这样,上面的代码块仍然无法工作。(这将抛出一个TypeError
因为doSomething
在您调用它时不是函数)
As far as standard practices go, you should always use the proper tool for the job.
就标准做法而言,您应该始终使用适当的工具来完成工作。
Axel Rauschmayer has a great post on scope and hoisting including es6 semantics: Variables and Scoping in ES6
Axel Rauschmayer 发表了一篇关于作用域和提升(包括 es6 语义)的精彩博文:ES6 中的变量和作用域
回答by gafi
Although using const
to define functions seems like a hack, but it comes with some great advantages that make it superior (in my opinion)
虽然使用const
来定义函数看起来像一个黑客,但它有一些很大的优势,使它更胜一筹(在我看来)
It makes the function immutable, so you don't have to worry about that function being changed by some other piece of code.
You can use fat arrow syntax, which is shorter & cleaner.
Using arrow functions takes care of
this
binding for you.
它使函数不可变,因此您不必担心该函数会被其他一些代码更改。
您可以使用更短更简洁的粗箭头语法。
使用箭头函数负责
this
为您绑定。
example with function
示例与 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
same example with const
同样的例子 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
回答by JMichaelTX
It has been three years since this question was asked, but I am just now coming across it. Since this answer is so far down the stack, please allow me to repeat it:
问这个问题已经三年了,但我现在才遇到它。由于这个答案在堆栈中太远了,请允许我重复一遍:
Q:I am interested if there are any limits to what types of values can be set using const in JavaScript—in particular functions. Is this valid? Granted it does work, but is it considered bad practice for any reason?
问:我感兴趣的是,在 JavaScript 中使用 const 设置的值类型是否有任何限制——特别是函数。这是有效的吗?授予它确实有效,但它是否出于任何原因被认为是不好的做法?
I was motivated to do some research after observing one prolific JavaScript coder who alwaysuses const
statement for functions
, even when there is no apparent reason/benefit.
在观察了一位多产的 JavaScript 编码员后,我有动力去做一些研究,他总是使用const
语句 for functions
,即使没有明显的原因/好处。
In answer to "is it considered bad practice for any reason?" let me say, IMO, yes it is, or at least, there are advantagesto using function
statement.
回答“是否出于任何原因被认为是不好的做法?”让我说,IMO,是的,或者至少,使用语句有优势function
。
It seems to me that this is largely a matter of preference and style. There are some good arguments presented above, but none so clear as is done in this article:
Constant confusion: why I still use JavaScript function statementsby medium.freecodecamp.org/Bill Sourour, JavaScript guru, consultant, and teacher.
在我看来,这主要是偏好和风格的问题。上面提出了一些很好的论据,但没有像本文中所做的那样清楚:
持续困惑:为什么我仍然使用 JavaScript 函数语句由 medium.freecodecamp.org/Bill Sourour,JavaScript 大师、顾问和教师撰写。
I urge everyone to read that article, even if you have already made a decision.
我敦促每个人都阅读那篇文章,即使你已经做出了决定。
Here's are the main points:
以下是要点:
Function statements have two clear advantages over [const] function expressions:
Advantage #1: Clarity of intent
When scanning through thousands of lines of code a day, it's useful to be able to figure out the programmer's intent as quickly and easily as possible.Advantage #2: Order of declaration == order of execution
Ideally, I want to declare my code more or less in the order that I expect it will get executed.
This is the showstopper for me: any value declared using the const keyword is inaccessible until execution reaches it.
What I've just described above forces us to write code that looks upside down. We have to start with the lowest level function and work our way up.
My brain doesn't work that way. I want the context before the details.
Most code is written by humans. So it makes sense that most people's order of understanding roughly follows most code's order of execution.
与 [const] 函数表达式相比,函数语句有两个明显的优势:
优势一:意图清晰
每天扫描数千行代码时,能够尽可能快速、轻松地找出程序员的意图非常有用。优势#2:声明顺序==执行顺序
理想情况下,我想或多或少地按照我期望的执行顺序来声明我的代码。
这对我来说是最重要的:任何使用 const 关键字声明的值在执行到达之前都是不可访问的。
我刚刚在上面描述的内容迫使我们编写看起来颠倒的代码。我们必须从最底层的功能开始,然后逐步向上。
我的大脑不是那样工作的。我想要细节之前的上下文。
大多数代码是由人类编写的。因此,大多数人的理解顺序大致遵循大多数代码的执行顺序是有道理的。
回答by mrmaclean89
There are some very important benefits to the use of const
and some would say it should be used wherever possible because of how deliberate and indicative it is.
使用 有一些非常重要的好处const
,有些人会说应该尽可能使用它,因为它是多么深思熟虑和指示性。
It is, as far as I can tell, the most indicative and predictable declaration of variables in JavaScript, and one of the most useful, BECAUSE of how constrained it is. Why? Because it eliminates some possibilities available to var
and let
declarations.
据我所知,它是 JavaScript 中最具指示性和可预测性的变量声明,也是最有用的声明之一,因为它是多么受约束。为什么?因为它消除了一些可用于var
和let
声明的可能性。
What can you infer when you read a const
? You know all of the following just by reading the const
declaration statement, AND without scanning for other references to that variable:
当你阅读 a 时,你能推断出什么const
?您只需阅读const
声明语句即可了解以下所有内容,并且无需扫描对该变量的其他引用:
- the value is bound to that variable (although its underlying object is not deeply immutable)
- it can't be accessed outside of its immediately containing block
- the binding is never accessed before declaration, because of Temporal Dead Zone (TDZ) rules.
- 该值绑定到该变量(尽管它的底层对象不是非常不可变的)
- 它不能在其直接包含的块之外访问
- 由于临时死区 (TDZ) 规则,在声明之前永远不会访问绑定。
The following quote is from an articlearguing the benefits of let
and const
. It also more directly answers your question about the keyword's constraints/limits:
以下报价是从一篇文章争论的好处let
和const
。它还更直接地回答了您关于关键字约束/限制的问题:
Constraints such as those offered by
let
andconst
are a powerful way of making code easier to understand. Try to accrue as many of these constraints as possible in the code you write. The more declarative constraints that limit what a piece of code could mean, the easier and faster it is for humans to read, parse, and understand a piece of code in the future.Granted, there's more rules to a
const
declaration than to avar
declaration: block-scoped, TDZ, assign at declaration, no reassignment. Whereasvar
statements only signal function scoping. Rule-counting, however, doesn't offer a lot of insight. It is better to weigh these rules in terms of complexity: does the rule add or subtract complexity? In the case ofconst
, block scoping means a narrower scope than function scoping, TDZ means that we don't need to scan the scope backwards from the declaration in order to spot usage before declaration, and assignment rules mean that the binding will always preserve the same reference.The more constrained statements are, the simpler a piece of code becomes. As we add constraints to what a statement might mean, code becomes less unpredictable. This is one of the biggest reasons why statically typed programs are generally easier to read than dynamically typed ones. Static typing places a big constraint on the program writer, but it also places a big constraint on how the program can be interpreted, making its code easier to understand.
With these arguments in mind, it is recommended that you use
const
where possible, as it's the statement that gives us the least possibilities to think about.
诸如由
let
和提供的约束const
是使代码更易于理解的强大方式。尝试在您编写的代码中尽可能多地增加这些约束。限制一段代码含义的声明性约束越多,未来人类阅读、解析和理解一段代码就越容易、越快。诚然,
const
声明比声明有更多规则var
:块范围、TDZ、声明时分配、无重新分配。而var
语句仅表示函数作用域。然而,规则计数并没有提供很多洞察力。最好根据复杂性权衡这些规则:规则是增加还是减少复杂性?在这种情况下const
,块作用域意味着比函数作用域更窄的作用域,TDZ 意味着我们不需要从声明向后扫描作用域以便在声明之前发现用法,并且赋值规则意味着绑定将始终保留相同的参考。约束语句越多,一段代码就越简单。当我们对语句的含义添加约束时,代码变得不那么不可预测了。这是静态类型程序通常比动态类型程序更易于阅读的最大原因之一。静态类型对程序编写者施加了很大的约束,但它也对程序的解释方式施加了很大的约束,使其代码更易于理解。
考虑到这些论点,建议您
const
在可能的情况下使用,因为这是让我们考虑的可能性最小的陈述。