{"data":{"site":{"siteMetadata":{"title":"Gandalf The Blue","author":"ys"}},"markdownRemark":{"id":"70d2a52f-b3e0-55a9-8def-fd1863b74096","html":"<p>原文链接<a href=\"https://overreacted.io/on-let-vs-const/\">On let vs const</a></p>\n<p>我的<a href=\"/gandalfTheBlue/what-is-javascript-made-of/\">上一篇文章</a>包括下面这段话:</p>\n<blockquote>\n<p><strong><code class=\"language-text\">let</code> vs <code class=\"language-text\">const</code> vs <code class=\"language-text\">var</code></strong>: 通常你会选择 <code class=\"language-text\">let</code>。如果要禁止给变量重新赋值, 则可以使用 <code class=\"language-text\">const</code>. (有些代码库和程序员比较教条主义，当变量只赋值一次时，会强迫使用 <code class=\"language-text\">const</code>。)</p>\n</blockquote>\n<p>事实证明这是非常有争议的，引发了Twitter和Reddit上的激烈讨论。似乎大多数人的观点（或至少是最明确表达的观点）是，<em>应尽可能使用 <code class=\"language-text\">const</code></em>，只有在需要时才使用 <code class=\"language-text\">let</code>，并且可以使用 <a href=\"https://eslint.org/docs/rules/prefer-const\"><code class=\"language-text\">prefer-const</code></a> ESLint规则来强制执行。</p>\n<p>在本文中，我将简要总结我遇到的一些支持论点和反驳论点，以及我对该话题的个人结论。</p>\n<h2 id=\"为什么-prefer-const\"><a href=\"#%E4%B8%BA%E4%BB%80%E4%B9%88-prefer-const\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>为什么 <code class=\"language-text\">prefer-const</code></h2>\n<ul>\n<li><strong>一种论点是</strong>: 每次都要在<code class=\"language-text\">let</code>和<code class=\"language-text\">const</code>之间进行选择是一种心智负担。“始终在可行的地方使用 <code class=\"language-text\">const</code>”之类的规则使你不必再考虑它，并且可以由linter强制执行。</li>\n<li><strong>重新赋值可能引起bug</strong>: 在较长的函数中，重新分配变量很容易导致遗漏，这可能会导致bug。 特别是在闭包中，<code class=\"language-text\">const</code>使你更有信心，你将始终“看到”相同的值。</li>\n<li><strong>关于可变的学习</strong>: 刚接触JavaScript的人经常会感到困惑，认为<code class=\"language-text\">const</code>意味着不可变性。 但是，有人可能会指出，学习变量变动(mutation)和赋值之间的区别很重要，并且使用<code class=\"language-text\">const</code>会迫使你尽早应对这种区别。</li>\n<li><strong>无用的赋值</strong>: 有时候赋值是根本没有意义的。 例如，使用React Hooks时，从诸如<code class=\"language-text\">useState</code>之类的Hook中获取的值更像参数。 它们沿一个方向流动。 在赋值中发现错误有助于你更早地了解React数据流。</li>\n<li><strong>性能优化</strong>: 偶尔有人声称，由于事先知道不会重新分配变量，因此JavaScript引擎可以使使用<code class=\"language-text\">const</code>的代码运行得更快。</li>\n</ul>\n<h2 id=\"为什么不-prefer-const\"><a href=\"#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D-prefer-const\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>为什么不 <code class=\"language-text\">prefer-const</code></h2>\n<ul>\n<li><strong>意图的丢失</strong>: 如果我们在所有可以使用的地方强制使用<code class=\"language-text\">const</code>，那么对于判断某些变量应不应该被重新赋值是否<em>重要</em>，我们将失去表达这种信息的能力。</li>\n<li><strong>不可变性的困扰</strong>: 在每次关于为什么你应该首选<code class=\"language-text\">const</code>的讨论中，总会有人对不变性感到困惑。 这并不奇怪，因为赋值和变量变动都使用相同的<code class=\"language-text\">=</code>运算符。 作为回应，人们通常被告知他们应该“只是学习该门语言”。 但是，相反的论点是，如果可以防止大多数初学者犯错误的功能同时使初学者感到困惑，那么它其实并不是很有用。 不幸的是，它无助于防止跨越模块并影响每个人的变量变动错误。</li>\n<li><strong>避免重新申明的压力</strong>: <code class=\"language-text\">const</code>优先的代码库给在某种条件下会重新分配变量的情况制造了不能使用<code class=\"language-text\">let</code>的压力。 例如，你可能编写<code class=\"language-text\">const a = cond ? b : c</code>而不是<code class=\"language-text\">if</code>条件分支，即使<code class=\"language-text\">b</code>分支和<code class=\"language-text\">c</code>分支很复杂并且给它们指定明确的名称很奇怪。</li>\n<li><strong>重新赋值可能不会引起bug</strong>: 在三种常见的情况下重新赋值会导致错误：当scope很大（例如模块scope或庞大的函数）时，当值是参数时（因此它等于传递的值之外的值是不可预料的）， 以及在嵌套函数中使用变量时。 但是，在许多代码库中，大多数变量都不满足以上任何一种情况，并且根本无法将参数标记为常量。</li>\n<li><strong>无法性能优化</strong>: 据我了解，即使你使用<code class=\"language-text\">var</code>或<code class=\"language-text\">let</code>，javascript引擎也已经知道哪些变量仅被赋值一次。 如果我们坚持推断，那么我们也可以推断额外的检查会“创造”性能成本，而不是降低性能成本。 实际上，javascript引擎非常聪明。</li>\n</ul>\n<h2 id=\"我的结论\"><a href=\"#%E6%88%91%E7%9A%84%E7%BB%93%E8%AE%BA\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>我的结论</h2>\n<p>我根本不在乎。</p>\n<p>我将使用代码库中已经存在的任何约定。</p>\n<p>如果你在乎的话，请使用可自动检查和修复此问题的linter，以免将<code class=\"language-text\">let</code>更改为<code class=\"language-text\">const</code>造成代码评审的延误。</p>\n<p>最后请记住，linters的存在是为<em>你</em>服务的。 如果一个linter规则使你和你的团队感到不快，请将其删除。 这可能不值得。 请从自己的错误中学习。</p>","timeToRead":1,"frontmatter":{"title":"let还是const","date":"December 22, 2019"},"fields":{"slug":"/on-let-vs-const/","langKey":"en"}}},"pageContext":{"slug":"/on-let-vs-const/","previous":{"fields":{"slug":"/refresh-react-project-in-IE11-404-error/","langKey":"en","directoryName":"refresh-react-project-in-IE11-404-error"},"frontmatter":{"title":"React 项目在IE11下刷新页面出现404错误"}},"next":{"fields":{"slug":"/common-mistakes-react-hooks/","langKey":"en","directoryName":"common-mistakes-react-hooks"},"frontmatter":{"title":"2020年编写React组件(hooks)的五个常见错误"}},"translations":[]}}