“let”和“var”之间的区别是什么堆栈溢出 最近30次来自stackoverflow.com 2024-06-28T01:18:36Z https://stackoverflow.com/feeds/question/762011 https://creativecommons.org/licenses/by-sa/4.0/rdf https://stackoverflow.com/q/762011 6281 “let”和“var”之间的区别是什么? TM。 https://stackoverflow.com/users/12983 2009年4月17日20:09:26Z 2023-10-25T06:27:29Z <p>ECMAScript 6推出<a href=“https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let“rel=”noreferrer“>let语句</p><p>我听说它被描述为一个局部变量,但我仍然不太确定它的行为与<code>var</code>关键字有什么不同</p><p>有什么区别?何时应该使用<code>来代替<code>var</p> https://stackoverflow.com/questions/762011/-/762018#762018 186 Ben S回答“let”和“var”的区别是什么? 本·S https://stackoverflow.com/users/68507 2009年4月17日20:11:47Z 2019-06-24T02:52:39Z <p>这里有一个<a href=“https://developer.mozilla.org/en/New_in_JavaScript_1.7#Block_scope_with_let“rel=”noreferrer“>对<code>let</code>关键字</a>的解释以及一些示例</p><区块报价><p><code>let</code>的工作原理与<code>var</code>非常相似。主要区别是变量的范围是整个封闭函数</p></blockquote><p><a href=“http://en.wikipedia.org/wiki/JavaScript#Version_history“rel=”noreferrer“>维基百科上的这个表显示了哪些浏览器支持Javascript 1.7</p><p>请注意,只有Mozilla和Chrome浏览器支持它。IE、Safari和其他可能不支持</p> https://stackoverflow.com/questions/762011/-/762297#762297 66 olliej回答“let”和“var”之间的区别是什么? 奥利耶 https://stackoverflow.com/users/784 2009年4月17日21:38:22Z 2019-06-24T02:53:08Z <p>有一些细微的差异&mdash<code>让</code>作用域的行为与其他任何语言中的变量作用域行为类似</p><p>例如,它作用于封闭块,它们在声明之前不存在,等等</p><p>然而值得注意的是,<code>let</code>只是较新Javascript实现的一部分,具有不同程度的<a href=“http://caniuse.com/#search=let“rel=”noreferrer“>浏览器支持</p> https://stackoverflow.com/questions/762011/-/114444416#11444416 8229 ThinkingStiff关于“let”和“var”之间的区别是什么的回答? 思维僵化 https://stackoverflow.com/users/918414 2012年7月12日T02:53:34Z 2023-09-18T16:43:09Z <h1>范围界定规则</h1><p>主要区别在于范围规则。关键字<code>var</code>声明的变量的作用域是立即数函数体(因此是函数作用域),而<code>let</code>var的作用域则是立即数<em>封闭</em>块(因此是块作用域)</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>函数run(){var foo=“foo”;设bar=“bar”;console.log(foo,bar);//Foo酒吧{var moo=“Mooo”设baz=“Bazz”;console.log(moo,baz);//穆奥巴兹}console.log(moo);//穆奥控制台.log(baz);//引用错误}运行()</代码></pre></div></div></p><p><code>let</code>关键字被引入该语言的原因是函数范围令人困惑,并且是JavaScript中错误的主要来源之一</p><p>从<a href=“https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example“>另一个堆栈溢出问题:</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”>var funcs=[];//让我们创建3个函数对于(var i=0;i&lt;3;i++){//并将其存储在函数中funcs[i]=函数(){//每个都应该记录其值。console.log(“我的值:”+i);};}对于(var j=0;j&lt;3;j++){//现在让我们逐一看看函数[j]();}</code></pre></div></div></p><p><code>我的值:3每次<code>funcs[j]()时都会输出到控制台</由于匿名函数被绑定到同一个变量,因此调用了code></p><p>人们必须创建立即调用的函数来从循环中捕获正确的值,但这也很麻烦</p><h1>吊装</h1><p>用<code>var</code>关键字声明的变量是<a href=“https://dev.to/godticampy/the-secret-of-hoisting-in-javascript-egi“rel=”noreferrer“>已提升并初始化<em>,这意味着即使在声明它们之前,也可以在其封闭范围内访问它们,但在到达声明语句之前,它们的值是未定义的:</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>函数检查提升(){console.log(foo);//未定义var foo=“foo”;console.log(foo);//}检查吊装()</代码></pre></div></div></p><p><code>让</code>变量是<a href=“https://stackoverflow.com/questions/31219420/are-variables-declared-with-let-or-const-hosted“>已挂起,但<em>在评估其定义之前未初始化。在初始化之前访问它们会导致<code>ReferenceError。该变量称为位于https://stackoverflow.com/questions/33198849/what-is-the-temporal-dead-zone“>从块开始到处理声明语句的时间死区</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>函数检查提升(){console.log(foo);//引用错误让foo=“foo”;console.log(foo);//}检查吊装()</代码></pre></div></div></p><h1>创建全局对象属性</h1><p>在顶层,与<code>var不同,<code>let</code>不在全局对象上创建属性:</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”>var foo=“foo”;//全局范围的让bar=“bar”;//全局范围,但不是全局对象的一部分console.log(window.foo);//console.log(window.bar);//未定义</code></pre></div></div></p><h1>重新申报</h1><p>在严格模式下,<code>var</code>将允许您在同一范围内重新声明同一变量,而<code>让</code>引发SyntaxError</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>'use strict';var foo=“foo1”;var foo=“foo2”;//没问题,“foo1”被替换为“foo2”。设bar=“bar1”;设bar=“bar2”;//SyntaxError:标识符“bar”已声明</code></pre></div></div></p> https://stackoverflow.com/questions/762011/-/25355080#25355080 27 abroz回答“let”和“var”的区别是什么? 阿布罗斯 https://stackoverflow.com/users/2803080 2014年8月18日T00:58:29Z 2017-10-09T22:24:59Z <p>这里有一个例子来补充其他人已经写过的内容。假设您要创建一个函数数组,<code>adderFunctions</code>,其中每个函数都接受一个Number参数,并返回该参数和函数在数组中的索引之和。尝试使用<code>var</code>关键字通过循环生成<code>adderFunctions</p><pre><code>//加法器函数数组。var加法器函数=[];对于(var i=0;i&lt;1000;i++){//我们希望索引i处的函数将索引添加到其参数中。加法器函数[i]=函数(x){//我在这里要做什么?返回x+i;};}var add12=加法器函数[12];//哦哦。该函数被绑定到外部作用域中的i,当前为1000。console.log(add12(8)===20);//=&gt;控制台.log(add12(8)===1008);//=&gt;真的控制台.log(i);//=&gt;1000//情况变得更糟了。i=-8;控制台.log(add12(8)===0);//=&gt;真的</code></pre><p>上述过程没有生成所需的函数数组,因为<code>i</code>的范围超出了创建每个函数的<code>for</code>block的迭代范围。相反,在循环末尾,每个函数闭包中的<code>i</code>是指<code>adderFunctions</code>中每个匿名函数在循环末尾的值(1000)。这根本不是我们想要的:我们现在在内存中有一个由1000个不同函数组成的数组,它们的行为完全相同。如果我们随后更新<code>i</code>的值,变异将影响所有<code>加法器函数</p><p>但是,我们可以使用<code>let</code>关键字重试:</p><pre><code>//让我们再试一次。//注意:我们正在使用另一个ES6关键字const来表示不需要的值//被重新分配。const和let具有类似的作用域行为。常量加法器函数=[];for(设i=0;i&lt;1000;i++){//注意:这次我们使用的是更新的箭头函数语法,但是//使用上一示例中的“function(x){…”语法//这里不会更改显示的行为。加法器函数[i]=x=&gt;x+i;}const add12=加法器函数[12];//耶!行为如预期。console.log(add12(8)===20);//=&gt;真的//我的范围没有扩展到for循环之外。控制台.log(i);//=&gt;ReferenceError:未定义i</code></pre><p>这一次,<code>i</code>在<code>for</code>loop的每次迭代中都会反弹。现在,每个函数都会在创建函数时保留<code>i的值,并且<code>adderFunctions</code>的行为符合预期</p><p>现在,将这两种行为混合在一起,您可能会看到为什么不建议在同一脚本中混合使用较新的<code>let</code>和<code>const</code>var</code>。这样做可能会导致一些非常混乱的代码</p><pre><code>const doubleAdderFunctions=[];对于(var i=0;i&lt;1000;i++){常数j=i;doubleAdderFunctions[i]=x=&gt;x+i+j;}const add18=双加法器函数[9];const add24=双加法器函数[12];//调试这样的情况并不有趣,尤其是当//代码比这个示例中的代码更复杂。控制台.log(add18(24)===42);//=&gt;控制台.log(add24(18)===42);//=&gt;控制台.log(add18(24)===add24(18));//=&gt;控制台.log(add18(24)===2018);//=&gt;console.log(add24(18)===2018);//=&gt;控制台.log(add18(24)===1033);//=&gt;真的控制台.log(add24(18)===1030);//=&gt;真的</code></pre><p>不要让这种事发生在你身上。使用线头</p><区块报价><p><strong>注意:</strong>这是一个教学示例,旨在演示循环中的<code>var</code>/<code>let</code>行为,以及易于理解的函数闭包。这将是一种可怕的数字相加方式。但是,在其他环境中的现实世界中可能会遇到在匿名函数闭包中捕获数据的通用技术。基督教青年会</p></blockquote> https://stackoverflow.com/questions/762011/-/28897059#28897059 71 用vlio20回答“let”和“var”的区别是什么? vlio20型 https://stackoverflow.com/users/1691423 2015年3月6日10时41分10秒 2023-02-06T10:02:48Z <p>以下是这两者之间的区别示例:<br/><img src=“https://i.sstatic.net/dqNYW.png“alt=”在此处输入图像描述“/></p><p>如您所见,<code>var j</code>变量的值仍在for循环作用域(块作用域)之外,但<code>let i</code>变量在for循环范围之外未定义</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>“use strict”;console.log(“变量:”);对于(var j=0;j&lt;2;j++){控制台日志(j);}控制台日志(j);console.log(“let:”);for(设i=0;i&lt;2;i++){控制台.log(i);}控制台.log(i)</代码></pre></div></div></p> https://stackoverflow.com/questions/762011/-/30479554#30479554 831 Gurpreet Singh回答“let”和“var”的区别是什么? 格普里特 https://stackoverflow.com/users/1750604 2015年5月27日T10:16:23Z 2019-10-29T08:47:10Z <p>还可以使用<code>let</code>来避免闭包问题。它绑定新值,而不是保留旧引用,如下面的示例所示</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>for(var i=1;i&lt;6;i++){$(“#div”+i)点击(函数(){console.log(i);});}</code></pre><pre-class=“snippet-code-html lang-html prettyprint-override”><code>&lt;script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js“&gt;&lt;/script&gt;&它;p&gt;单击每个数字将登录到控制台:&lt/p&gt;&它;div id=“div1”&gt;1&lt/div&gt;&它;div id=“div2”&gt;2&lt/div&gt;&它;div id=“div3”&gt;3&lt/div&gt;&它;div id=“div4”&gt;4&lt/div&gt;&它;div id=“div5”&gt;5&lt/div&gt</代码></pre></div></div></p><p>上面的代码演示了一个典型的JavaScript关闭问题。对<code>i</code>变量的引用存储在click处理程序闭包中,而不是<code>i</code>的实际值</p><p>每个单击处理程序都会引用同一个对象,因为只有一个计数器对象可以容纳6个对象,所以每次单击都会得到6个对象</p><p>一般的解决方法是将其封装在匿名函数中,并将<code>i</code>作为参数传递。现在还可以通过使用<code>let</code>来避免此类问题,如下面的代码所示</p><p><sub>(在Chrome和Firefox 50中测试)</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>for(让i=1;i&lt;6;i++){$(“#div”+i)点击(函数(){console.log(i);});}</code></pre><pre-class=“snippet-code-html lang-html prettyprint-override”><code>&lt;script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js“&gt;&lt;/script&gt;&它;p&gt;单击每个数字将登录到控制台:&lt/p&gt;&它;div id=“div1”&gt;1&lt/div&gt;&它;div id=“div2”&gt;2&lt/div&gt;&它;div id=“div3”&gt;3&lt/div&gt;&它;div id=“div4”&gt;4&lt/div&gt;&它;div id=“div5”&gt;5&lt/div&gt</代码></pre></div></div></p> https://stackoverflow.com/questions/762011/-/30606474#30606474 145 由Lcf.vs回答“let”和“var”的区别是什么? 液化石油气vs https://stackoverflow.com/users/1309106 2015年6月2日20:59:17Z 2016年7月14日14T14:13:44Z <p>公认的答案缺少一点:</p><预><代码>{设a=123;};控制台.log(a);//ReferenceError:未定义</code></pre> https://stackoverflow.com/questions/762011/-/31931350#31931350 16 RDoc回答“let”和“var”的区别是什么? RDoc公司 https://stackoverflow.com/users/2532992 2015年8月11日00:35:29Z 2016年11月28日T09:31:05Z <p>看起来,至少在Visual Studio 2015中,TypeScript 1.5“var”允许在一个块中多次声明相同的变量名,而“let”则不允许</p><p>这不会生成编译错误:</p><pre><code>var x=1;var x=2;</code></pre><p>这将:</p><pre><code>让x=1;设x=2;</code></pre> https://stackoverflow.com/questions/762011/-/34839890#34839890 35 zangw回答“let”和“var”的区别是什么? 藏族 https://stackoverflow.com/users/3011380 2016年1月17日15:11:31Z 2017年1月1日T00:41:23Z <ul><li><p><del><strong>变量不吊装</strong></del></p><p><del><code>let</code>不会将</strong>提升到它们出现的块的整个范围。相比之下,<code>var</code>可以如下提升</删除></p><预><代码>{console.log(抄送);//未定义。吊装引起的var cc=23;}{控制台.log(bb);//ReferenceError:bb未定义设bb=23;}</code></pre><p>实际上,Per@Bergi,<a href=“https://stackoverflow.com/questions/31219420/are-variables-declared-with-let-or-const-not-hoisted-in-es6“>吊起<code>var和<code>let</p></li><li><p>垃圾收集</p><p><code>let</code>的块范围与闭包和垃圾收集有关,可以回收内存。考虑一下</p><pre><code>功能过程(数据){//...}var hugeData={..};流程(hugeData);var btn=文档.getElementById(“mybutton”);btn.addEventListener(“点击”,功能点击(evt){//....});</code></pre><p>单击处理程序回调根本不需要<code>hugeData变量。理论上,在<code>进程(..)</code>运行后,可以对巨大的数据结构<code>hugeData</code>进行垃圾收集。然而,有些JS引擎可能仍然需要保留这个庞大的结构,因为<code>单击</code>函数在整个范围内都有一个闭包</p><p>然而,块范围可以使这个巨大的数据结构被垃圾收集</p><pre><code>功能过程(数据){//...}{//此块内声明的任何内容都可以被垃圾收集设hugeData={..};流程(hugeData);}var btn=文档.getElementById(“mybutton”);btn.addEventListener(“点击”,功能点击(evt){//....});</code></pre></li><li><p><strong><code>让</code>循环</strong></p><p>循环中的<code>let</code>可以<strong>将其</strong>重新绑定到循环的每次迭代,确保将上一次循环迭代结束时的值重新分配给它。考虑一下</p><pre><code>//打印5次对于(var i=0;i&lt;5;++i){setTimeout(函数(){控制台.log(i);}, 1000); }</code></pre><p>但是,将<code>var</code>替换为<code>let</p><pre><code>//打印1、2、3、4、5。现在for(设i=0;i&lt;5;++i){setTimeout(函数(){控制台.log(i);}, 1000); }</code></pre><p>因为<code>让</code>使用这些名称为a)初始化表达式b)每个迭代(在计算增量表达式之前)创建一个新的词汇环境,所以更多详细信息是<a href=“https://stackoverflow.com/a/30900289/3011380“>此处</a></p></li></ul> https://stackoverflow.com/questions/762011/-/35585468#35585468 334 John Slegers回答“let”和“var”的区别是什么? 约翰·斯利格斯 https://stackoverflow.com/users/1946501 2016年2月23日18:35:27Z 2022-12-28年T17:05:34Z <h3><code>let</code>和<code>var</code>之间的区别是什么</h3><ul><li>使用<code>var</code>语句定义的变量在整个过程中都是已知的https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/function网站“rel=”noreferrer“><strong>函数</strong></a>它是在函数开始时在中定义的。<em>(*)</em></li><li>使用<code>let语句定义的变量只有在<A href=“https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/block(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/block)“rel=”noreferrer“><strong>块</strong></a>从定义开始,它就在中定义。<em>(**)</em></li></ul><p>要理解差异,请考虑以下代码:</p><pre><code>//i此处未知//此处不知道j//k在此已知,但未定义//我在这里不认识功能循环(arr){//我在这里是已知的,但没有定义//此处不知道j//k在这里是已知的,但只有一个值,称为第二个时间循环//我在这里不认识对于(var i=0;i&lt;arr.length;i++){//我在这里是已知的,并且有一个值//此处不知道j//k在这里是已知的,但只有一个值,称为第二个时间循环//我在这里不认识};//我在这里是已知的,并且有一个值//此处不知道j//k在这里是已知的,但只有一个值,称为第二个时间循环//我在这里不认识for(设j=0;j&lt;arr.length;j++){//我在这里是已知的,并且有一个值//j在这里是已知的,并且有一个值//k在这里是已知的,但只有一个值,称为第二个时间循环//我在这里不认识};//我在这里是已知的,并且有一个值//此处不知道j//k在这里是已知的,但只有一个值,称为第二个时间循环//我在这里不认识}回路([1,2,3,4]);对于(var k=0;k&lt;arr.length;k++){//我在这里不认识//此处不知道j//k在这里是已知的,并且有一个值//我在这里不认识};for(设l=0;l&lt;arr.length;l++){//我在这里不认识//此处不知道j//k在这里是已知的,并且有一个值//l在这里是已知的,并且有一个值};回路([1,2,3,4]);//我在这里不认识//此处不知道j//k在这里是已知的,并且有一个值//我在这里不认识</code></pre><p>在这里,我们可以看到,我们的变量<code>j</code>只在第一个for循环中已知,而在前面和后面都不知道。然而,我们的变量<code>i</code>在整个函数中都是已知的</p><p>此外,考虑到块范围的变量在声明之前是未知的,因为它们没有被提升。也不允许在同一块中重新声明同一块范围内的变量。这使得块范围的变量比全局或函数范围的变量更不容易出错,全局或函数范围的变量是被提升的,在多个声明的情况下不会产生任何错误</p><小时/><h3>今天使用<code>let</code>安全吗</h3><p>有些人会认为,将来我们将只使用let语句,而var语句将过时。JavaScript专家<a href=“https://twitter.com/getify“rel=”noreferrer“><strong>凯尔·辛普森</strong></a>写道https://davidwalsh.name/for-and-against-let“rel=”noreferrer“><strong>这是一篇非常详尽的文章,阐述了为什么他认为情况不会如此</strong></a></p><p>然而,今天的情况绝对不是这样。实际上,我们需要问问自己使用<code>let语句是否安全。这个问题的答案取决于您的环境:</p><ul><li><p>如果您正在编写服务器端JavaScript代码(<a href=“https://nodejs.org/en/“rel=”noreferrer“><strong>Node.js</strong></a>),您可以安全地使用<code>let语句</p></li><li><p>如果您正在编写客户端JavaScript代码并使用基于浏览器的转发器(如<a href=“https://github.com/google/traceur-compiler“rel=”noreferrer“>Traceur或https://github.com/babel/babel-standalone“rel=”noreferrer“><strong>babel-standalone</strong></a>),您可以安全地使用<code>let</code>语句,但是您的代码在性能方面可能不是最佳的</p></li><li><p>如果您正在编写客户端JavaScript代码并使用基于节点的转发器(如<a href=“https://github.com/google/traceur-compiler/wiki/Compiling-Offline“rel=”noreferrer“><strong>traceur shell脚本</strong></a>或<a href=”https://babeljs.io网址/“rel=”noreferrer“><strong>Babel</strong></a>),您可以安全地使用<code>let</code>语句。而且,由于您的浏览器只知道传输的代码,因此性能缺陷应该受到限制</p></li><li><p>如果您正在编写客户端JavaScript代码,并且不使用transpiler,则需要考虑浏览器支持</p><p>仍有一些浏览器根本不支持<code>let</code>:</p></li></ul><p><a href=“https://i.sstatic.net/J9kEC.png“rel=”noreferrer“><img src=”https://i.sstatic.net/J9kEC.png“alt=”在此处输入图像描述“/></a></p><小时/><h3>如何跟踪浏览器支持</h3><p>有关阅读此答案时哪些浏览器支持<code>let语句的最新概述,请参阅<a href=“http://caniuse.com/#search=let“rel=”noreferrer“><strong>这个<code>我可以使用</code>页面</strong></a></p><小时/><p><em>(*)全局和功能范围内的变量可以在声明之前进行初始化和使用,因为JavaScript变量<a href=“https://developer.mozilla.org/en-US/docs/Glossary/吊装“rel=”noreferrer“><strong>被提升</strong></a>。</em>这意味着声明总是被移动到作用域的顶部</p><p><em>(**)块作用域变量未提升</p> https://stackoverflow.com/questions/762011/-/37322132#37322132 -2 Gurucharan M K回答“let”和“var”之间的区别是什么? 古鲁查兰M K https://stackoverflow.com/users/4008968 2016年5月19日11:41:10Z 2022-12-28年T17:14:44 Z <p><a href=“https://en.wikipedia.org/wiki/ECMAScript#6th_Edition_-_ECMAScript_2015“rel=”nofollow noreferrer“>ECMAScript 6又添加了一个关键字来声明除“let”之外的“const”之外的变量</p><p>引入&quot;的主要目标;设“;和&quot;常量;超过;var(变量);是使用块作用域而不是传统的词汇作用域。<a href=“https://medial.com/@charan4u/ecmascript-6-beginer-guide-part-3-block-level-bindings-2b3cd5c5d408#.ev9gwp2jb“rel=”nofollow noreferrer“>我的文章非常简短地解释了“var”和“let”之间的区别,还涵盖了对“const”的讨论</p> https://stackoverflow.com/questions/762011/-/38140498#38140498 swaraj patil回答“let”和“var”的区别是什么? swaraj石灰岩 https://stackoverflow.com/users/3834128 2016年7月1日T08:22:35Z 2016年11月26日T16:33:53Z <p>现在,我认为使用<code>let</code>可以更好地将变量范围限定到语句块:</p><pre><code>函数printnums(){//我在这里不方便for(设i=0;i&lt;10;i+=){控制台.log(i);}//我在这里不方便//这里可以到达j对于(var j=0;j&lt;10;j++){控制台日志(j);}//这里可以到达j}</code></pre><p>我认为人们会在以后开始使用let,以便在JavaScript中使用类似于其他语言、Java、C#等的作用域</p><p>人们对JavaScript中的作用域没有明确的理解,这是早先犯下的错误</p><p>不支持使用<code>let</code>进行吊装</p><p>通过这种方法,JavaScript中存在的错误将被删除</p><p>请参阅<em><a href=“https://hacks.mozilla.org/2015/07/es6-in-depth-let-and-const/“rel=”nofollow noreferrer“>ES6深入:让和const更好地理解它</p> https://stackoverflow.com/questions/762011/-/38257233#38257233 17 Dmytro回答“let”和“var”的区别是什么? 德米特罗 https://stackoverflow.com/users/2012715 2016年7月8日0时21分11秒 2023-09-18T12:12:02Z <p><code>let非常有趣,因为它允许我们这样做:</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>(()=&gt;{var计数=0;for(设i=0;i&lt;2;++i){for(设i=0;i&lt;2;++i){for(设i=0;i&lt;2;++i){console.log(计数++);}}}})();</代码></pre><pre class=“snippet-code-css lang-css prettyprint-override”><code>.as-console-wrapper{max-hight:100%!important;}</code></pre></div></div></p><p>这将导致计数[0,7]</p><p>鉴于</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>(()=&gt;{var计数=0;对于(var i=0;i&lt;2;++i){对于(var i=0;i&lt;2;++i){对于(var i=0;i&lt;2;++i){console.log(计数++);}}}})();</代码></pre></div></div></p><p>仅计数[0,1]</p> https://stackoverflow.com/questions/762011/-/38510931#38510931 7 zloctb回答“let”和“var”的区别是什么? 兹洛克特布 https://stackoverflow.com/users/167376 2016年7月21日上午7:42:16Z 2016年11月26日T16:44:48Z <p>一些黑客使用<code>让</code>:</p><p>1</p><pre><code>let统计=[16,170,10];let[年龄、身高、年级]=统计;console.log(高度)</code></pre><p>2</p><pre><code>让x=120,y=12;[x,y]=[y,x];控制台.log(`x:${x}y:${y}`);</code></pre><p>3、</p><pre><code>let节点={type:“标识符”,名称:“foo”};让{type,name,value}=节点;console.log(类型);//“标识符”console.log(名称);//“foo”console.log(值);//未定义let节点={type:“标识符”};让{type:localType,name:localName=“bar”}=节点;console.log(localType);//“标识符”console.log(本地名称);//“酒吧”</code></pre><h3>使用<code>let</code>的Getter和setter:</h3><pre><code>let jar={Cookie数量:10,获取厨师(){返回this.numberOfCookies;},设置cookie(值){this.numberOfCookies=值;}};console.log(jar cookie)jar.cookies=7;console.log(jar cookie)</code></pre> https://stackoverflow.com/questions/762011/-/40035233#40035233 11 丹尼尔·索科洛夫斯基(Daniel Sokolowski)对“let”和“var”的区别是什么的回答? 丹尼尔·索科洛夫斯基 https://stackoverflow.com/users/913223 2016年10月14日T05:01:10Z 2019-01-12T05:29:57Z <p>如果我正确阅读了规范,那么谢天谢地,也可以利用<code>让</code><strong>避免<a href=“https://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript#592414“>自调用函数</a>用于模拟纯私有成员-<em>是一种流行的设计模式,它降低了代码的可读性,使调试复杂化,不增加真正的代码保护或其他好处-除了可能满足某人对语义的需求之外,所以停止使用它。/rant</em></p><pre><code>var SomeConstructor;{让privateScope={};SomeConstructor=函数SomeConstrator(){this.someProperty=“foo”;privateScope.hiddenProperty=“bar”;}SomeConstructor.prototype.showPublic=函数(){console.log(this.someProperty);//foo公司}SomeConstructor.prototype.showPrivate=函数(){console.log(privateScope.hiddenProperty);//酒吧}}var myInstance=新建SomeConstructor();myInstance.showPublic();myInstance.showPrivate();console.log(privateScope.hiddenProperty);//错误</code></pre><p>请参见“https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let#Emulating_private_interfaces“rel=”noreferrer“>仿真专用接口</p> https://stackoverflow.com/questions/762011/-/40775470#40775470 153 MichałPerłakowski回答“let”和“var”之间的区别是什么? 米夏·佩尔·阿库夫斯基 https://stackoverflow.com/users/3853934 2016年11月23日22:52:38Z 2022-03-21T15:02:02Z <h1><code>让</code></h1><h2>块范围</h2><p>使用<code>let</code>关键字声明的变量是块范围的,这意味着它们只能在<a href=“https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/block(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/block)“rel=”noreferrer“>块中声明了它们</p><h3>在顶层(函数外部)</h3><p>在顶层,使用<code>声明的变量不允许</code>在全局对象上创建属性</p><pre><code>var globalVariable=42;让blockScopedVariable=43;console.log(globalVariable);//42console.log(blockScopedVariable);//43console.log(this.globalVariable);//42console.log(this.blockScopedVariable);//未定义</code></pre><h3>函数内部</h3><p>在函数内部(但在块外部),<code>let与<code>var具有相同的作用域</p><pre><code>(()=&gt;{var函数ScopedVariable=42;让blockScopedVariable=43;console.log(functionScopedVariable);//42console.log(blockScopedVariable);//43})();console.log(functionScopedVariable);//ReferenceError:未定义functionScopedVariableconsole.log(blockScopedVariable);//ReferenceError:未定义blockScopedVariable</code></pre><h3>在块内</h3><p>在块内使用<code>let</code>声明的变量不能在该块外访问</p><预><代码>{var全局变量=42;让blockScopedVariable=43;console.log(globalVariable);//42console.log(blockScopedVariable);//43}console.log(globalVariable);//42console.log(blockScopedVariable);//ReferenceError:未定义blockScopedVariable</code></pre><h3>在循环内部</h3><p>在循环中使用<code>let</code>声明的变量只能在该循环中引用</p>(var i=0;i&lt;3;i++)的<pre><code>{变量j=i*2;}控制台.log(i);//控制台.log(j);//4for(设k=0;k&lt;3;k++){设l=k*2;}console.log(k类型);//未定义console.log(l类型);//未定义//尝试在此处执行console.log(k)或console.log(l)将引发ReferenceError。</code></pre><h3>带闭包的循环</h3><p>如果在循环中使用<code>let</code>而不是<code>var</code>,那么每次迭代都会得到一个新变量。这意味着您可以在循环中安全地使用闭包</p><pre><code>//记录三次,而不是我们的意思。对于(var i=0;i&lt;3;i++){setTimeout(()=&gt;控制台.log(i),0);}//按预期记录0、1和2。for(设j=0;j&lt;3;j++){setTimeout(()=&gt;控制台.log(j),0);}</code></pre><h2>时间死区</h2><p>因为<a href=“https://stackoverflow.com/q/33198849/3853934“>暂时死区</a>,使用<code>let</code>声明的变量在声明之前无法访问。尝试这样做会引发错误</p><pre><code>console.log(noTDZ);//未定义var noTDZ=43;console.log(hasTDZ);//ReferenceError:未定义hasTDZ设hasTDZ=42;</code></pre><h2>无需重新申报</h2><p>您不能使用<code>let</code>多次声明同一个变量。您也不能使用与使用<code>var</code>声明的另一个变量具有相同标识符的<code>let来声明变量</p><pre><code>var a;变量a;//效果很好。让b;设b;//语法错误:已声明标识符“b”变异系数c;设c;//语法错误:标识符“c”已声明</code></pre><h1><code>常量</h1><p><code>const</code>与<code>let非常相似-它是块范围的,并且有TDZ。然而,有两件事是不同的</p><h2>无重新签名</h2><p>无法重新分配使用const声明的变量</p><pre><code>const a=42;a=43;//TypeError:赋值给常量变量。</code></pre><p>注意,这并不意味着该值是不可变的。它的属性仍然可以更改</p><pre><code>const对象={};对象a=42;控制台.log(obj.a);//42</code></pre><p>如果你想要一个不可变的对象,你应该使用<a href=“https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze“rel=”noreferrer“><code>Object.freeze()</code></a></p><pre><code>constobj=对象冻结({a:40});对象a=42;控制台.log(obj.a);//40控制台.log(obj.b);//未定义</code></pre><h2>需要初始值设定项</h2><p>在使用const声明变量时,始终必须指定一个值</p><pre><code>const a;//语法错误:常量声明中缺少初始值设定项</code></pre> https://stackoverflow.com/questions/762011/-/41342735#41342735 2 anandharshan回答“let”和“var”的区别是什么? 阿南达尔山 https://stackoverflow.com/users/1453965 2016年12月27日T09:44:55Z 2017年4月30日T17:11:41Z <p>本文明确定义了var、let和const之间的区别</p><区块报价><p>const表示标识符不会被重新分配</p><p><code>let</code>是可以重新分配变量的信号,例如循环中的计数器,或算法中的值交换。它还发出信号变量将仅在其定义的块中使用,它并不总是整个包含函数</p><p><code>var</code>现在是定义变量时可用的最弱信号在JavaScript中。变量可以重新分配,也可以不重新分配变量可以用于也可以不用于整个函数,或仅用于块或循环的用途</p></blockquote><p><a href=“https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b“rel=”nofollow noreferrer“>https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b</a></p> https://stackoverflow.com/questions/762011/-/42954820#42954820 70 Alireza回答“let”和“var”的区别是什么? 阿里雷扎 https://stackoverflow.com/users/5423108 2017年3月22日T14:39:46Z 2023-09-18T16:24:03Z <p>主要区别是<strong>作用域</strong>的区别,而<strong>let只能在其声明的<strong]作用域内使用,例如在for循环中,<strong]var</strong>可以在循环外访问。从<a href=“https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let“rel=”nofollow noreferrer“>MDN(也来自MDN的示例):</p><区块报价><p><strong>让</strong>允许您声明范围仅限于使用它的块、语句或表达式的变量。这与<strong>var</strong>关键字不同,后者全局定义变量,或局部定义整个函数的变量,而不考虑块范围</p></blockquote><区块报价><p><strong>let</strong>声明的变量的作用域是定义变量的块,以及任何包含的子块。这样,<strong>让</strong>的工作方式与<strong>var非常相似。主要区别在于变量的范围是整个封闭函数:</p><pre><code>函数varTest(){var x=1;if(真){var x=2;//相同的变量!控制台.log(x);//2}控制台.log(x);//2}函数letTest(){设x=1;if(真){设x=2;//不同的变量控制台.log(x);//2}控制台.log(x);//1}`</code></pre><p>在程序和函数的顶层,与<strong>var不同,<strong>let不在全局对象上创建属性。例如:</p><pre><code>var x=“全局”;设y=“全局”;console.log(this.x);//&quot;全球;console.log(this.y);//未定义</code></pre></blockquote><区块报价><p>在块内使用时,让我们将变量的范围限制在该块内。注意<strong>var</strong>之间的区别,其范围在声明它的函数内</p><pre><code>var a=1;var b=2;如果(a===1){变量a=11;//范围是全球性的设b=22;//作用域在if-block中console.log(a);//11控制台.log(b);//22} 控制台.log(a);//11控制台.log(b);//2</code></pre></blockquote><p>另外,不要忘记它的ECMA6功能,所以它还没有完全支持,所以最好总是使用Babel等将其传输到ECMA5…有关访问的更多信息<a href=“https://babeljs.io网址“rel=”nofollow noreferrer“>巴贝尔网站</a></p> https://stackoverflow.com/questions/762011/-/44103318#44103318 35 用mormegil回答“let”和“var”的区别是什么? 肉豆蔻 https://stackoverflow.com/users/643826 2017-05-22T01:09:39分 2017-05-22T01:21:34Z <p>区别在于<a href=“https://en.wikipedia.org/wiki/变量_(computer_science)#Scope_and_extent“rel=”noreferrer“>Scope</a>与每个变量一起声明的变量</p><p>实际上,范围上的差异有许多有益的后果:</p><ol><li><code>让</code>变量仅在其最近的封闭</em>块中可见(<code>{…}</code>)</li><li><code>让</code>变量仅在声明变量后出现的代码行中可用(即使它们被提升)</li><li><code>let</code>变量不能由后续的<code>var</code>或<code]let</ccode>重新声明</li><li>全局<code>允许</code>变量不添加到全局<code>窗口</code>object中</li><li><code>让</code>变量易于与闭包一起使用(它们不会导致<a href=“https://en.wikipedia.org/wiki/Race_condition#软件“rel=”noreferrer“>竞争条件)</li></ol><p><code>施加的限制使</code>降低了变量的可见性,并增加了早期发现意外名称冲突的可能性。这样可以更容易地跟踪和推理变量,包括它们的<a href=“https://en.wikipedia.org/wiki/Unreachable_memory(无法访问的内存)“rel=”noreferrer“>可达性(帮助回收未使用的内存)</p><p>因此,当在大型程序中使用时,或者当独立开发的框架以新的、意想不到的方式组合时,<code>让</code>变量不太可能导致问题</p><p>如果您确信在循环中使用闭包(#5)或在代码中声明外部可见的全局变量(#4)时需要单一绑定效果,那么<code>var</code>可能仍然有用。如果<a href=“https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export“rel=”noreferrer“><code>export</code></a>从transpiler空间迁移到核心语言</p><h1>示例</h1><p><strong>1。在最近的封闭块外不可用:</strong>此代码块将引发引用错误,因为第二次使用<code>x</code>发生在用<code>let声明的块之外:</p><预><代码>{设x=1;}console.log(`x是${x}`);//解析期间ReferenceError:“x未定义”。</code></pre><p>相比之下,使用<code>var</code>的同一个示例可以工作</p><p><strong>2。声明前不使用:</strong><br>此代码块将在代码运行之前抛出<code>ReferenceError</code>,因为<code>x</code>是在声明之前使用的:</p><预><代码>{x=x+1;//解析期间ReferenceError:“x未定义”。设x;console.log(`x是${x}`);//从不跑步。}</code></pre><p>相反,使用<code>var</code>的同一示例在解析和运行时不会抛出任何异常</p><p><strong>3。无重新声明:</strong>以下代码演示了使用<code>let</code>声明的变量以后可能无法重新声明:</p><pre><code>让x=1;设x=2;//语法错误:已声明标识符“x”</code></pre><p><strong>4。未附加到<code>窗口的全局变量:</strong></p><pre><code>var button=“我的名字太普通了,所以我会引发事故。”;let link=“虽然我的名字很常见,但我很难从其他JS文件访问。”;console.log(链接);//好 啊console.log(window.link);//未定义(好!)console.log(window.button);//好 啊</code></pre><p><strong>5。使用方便:</strong>用<code>var</code>声明的变量不能很好地处理循环内的闭包。下面是一个简单的循环,它输出变量<code>i</code>在不同时间点的值序列:</p><pre><code>for(设i=0;i&lt;5;i++){console.log(`i是${i}`),125/*ms*/);}</code></pre><p>具体而言,该输出:</p><pre><code>i为0我是1我是2岁我是3岁我是4岁</code></pre><p>在JavaScript中,我们使用变量的时间通常比创建变量的时间晚得多。当我们用传递给<code>setTimeout的闭包延迟输出来演示这一点时:</p><pre><code>for(设i=0;i&lt;5;i++){setTimeout(_=&gt;console.log(`i是${i}`),125/*ms*/);}</code></pre><p>。。。只要我们坚持使用<code>let</code>,输出就保持不变。相反,如果我们使用了<code>var i:</p>(var i=0;i&lt;5;i++)的<pre><code>{setTimeout(_=&gt;console.log(`i是${i}`),125/*ms*/);}</code></pre><p>。。。循环意外输出“i是5”五次:</p><pre><code>i为5我5岁我5岁我5岁我5岁</code></pre> https://stackoverflow.com/questions/762011/-/46989846#46989846 11 穆斯林沙沙文对“let”和“var”的区别是什么的回答? 穆斯林沙沙文 https://stackoverflow.com/users/1279118 2017年10月28日T12:42:16Z 2017年10月28日T12:42:16Z <p>var是全局范围(可提升)变量</p><p><code>let和<code>const是块作用域</p><区块报价><p>测试.js</p></blockquote><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>{设l=“let”;const c=“const”;var v=“var”;v2='var 2';}console.log(v,this.v);console.log(v2,this.v2);控制台.log(l);//ReferenceError:未定义l控制台.log(c);//ReferenceError:c未定义</code></pre></div></div></p> https://stackoverflow.com/questions/762011/-/50405997#50405997 -2 纽兰回答:“let”和“var”有什么区别? 纽兰 https://stackoverflow.com/users/8675704 2018年5月18日07时27分41秒 2018年5月18日07时27分41秒 <p>签入此链接<a href=“https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let“rel=”nofollow noreferrer“>MDN</a></p><pre><code>让x=1;如果(x===1){设x=2;控制台.log(x);//预期输出:2}控制台.log(x);//预期输出:1</code></pre> https://stackoverflow.com/questions/762011/-/50468637#50468637 9 Ankur Soni回答“let”和“var”的区别是什么? 安库尔·索尼 https://stackoverflow.com/users/3296607 2018-05-22T13:12:36Z 2018年5月22日13:22:19Z <p><strong>使用时<code>让</code></p><p><code>let</code>关键字将变量声明附加到它所包含的任何块(通常是<code>{..}</code>pair)的作用域。换句话说,<code]let</code>隐式劫持了任何块的作用域作为其变量声明</p><p><code>let无法在<code>窗口</code>对象中访问变量,因为它们无法全局访问</p><pre><code>函数a(){{//这是let变量的最大范围设x=12;}控制台.log(x);}a();//未捕获引用错误:未定义x</code></pre><p><strong>使用<code>var时</code></strong></p><p><code>var</code>和ES5中的变量在函数中具有作用域,这意味着变量在函数内有效,而在函数本身之外无效</p><p><code>var</code>变量可以在<code>窗口中访问,因为它们不能全局访问</p><pre><code>function a(){//这是var变量的最大范围{ var x=12;}控制台.log(x);}a();//12</code></pre><p><strong>如果您想了解更多信息,请继续阅读以下内容</p><p>关于范围的一个最著名的面试问题也可以满足<code>let和<code>var的准确使用,如下所示</p><p><strong>使用<code>时让</code></p><pre><code>for(设i=0;i&lt;10;i++){设置超时(函数a(){控制台.log(i)//打印0到9,这简直就是AWW!!!}, 100*i);}</code></pre><p>这是因为在使用<code>let</code>时,对于每个循环迭代,变量都有作用域并有自己的副本</p><p><strong>使用<code>var</code>时</p>(var i=0;i&lt;10;i++)的<pre><code>{设置超时(函数a(){控制台.log(i)//打印10乘以10}, 100*i);}</code></pre><p>这是因为在使用<code>var</code>时,对于每个循环迭代,变量都有作用域并具有共享副本</p> https://stackoverflow.com/questions/762011/-/51724500#51724500 N Randhawa回答“let”和“var”的区别是什么? N兰德哈瓦 https://stackoverflow.com/users/4854721 2018-08-07T10:25:57Z 2018年8月13日14:02:08Z <p>如上所述:</p><区块报价><p>区别在于范围界定<code>var</code>的作用域是最近的<strong>函数块</strong>和<code>let</code>的作用域为<strong>最近的封闭块</strong>可以小于功能块。如果在任何外部,两者都是全局的块。让我们看一个例子:</p></blockquote><p><strong>示例1:</p><p>在我的两个示例中,我都有一个函数<code>myfunc</code><code>myfunc包含一个等于10的变量。在我的第一个示例中,我检查<code>myvar</code>是否等于10(<code>myvar==10)。如果是,我可以使用关键字<code>var</code>声明一个变量<code>myvar</code>(现在我有两个myvar变量),并为其分配一个新值(20)。在下一行中,我在控制台上打印它的值。在条件块之后,我再次在控制台上打印<code>myvar</code>的值。如果查看<code>myfunc</code>的输出,<code>myvar</code>的值等于20</p><p><a href=“https://i.sstatic.net/sWpnR.png网址“rel=”nofollow noreferrer“><img src=”https://i.sstatic.net/sWpnR.png网址“alt=”let keyword“></a></p><p><strong>示例2:在我的第二个示例中,我没有在条件块中使用<code>var</code>关键字,而是使用<code>let</code>keyword声明<code>myvar。现在,当我调用<code>myfunc时,会得到两个不同的输出:<code>myvar=20</p><p>因此,区别很简单,即其范围</p> https://stackoverflow.com/questions/762011/-/52244844#52244844 19 Willem van der Veen对“let”和“var”的区别是什么的回答? 威廉·范德维恩 https://stackoverflow.com/users/8059459 2018年9月9日T13:08:18Z 2018年9月10日7:39:18Z <h2>功能VS块范围:</h2><p><code>var</code>和<code>let</code>之间的主要区别是,用<code]var</code>声明的变量是函数范围内的。而用<code>let</code>声明的函数是<strong>块范围的</strong>。例如:</p><pre><code>函数testVar(){if(真){var foo='foo';}console.log(foo);}testVar();//日志“foo”函数testLet(){if(真){设bar=“bar”;}console.log(bar);}testLet();//参考误差//bar的作用域是if语句的块</code></pre><p><strong>变量带有<code>var</code>:</strong></p><p>当第一个函数<code>testVar</code>被调用时,变量foo(用<code>var</code>声明)仍然可以在<code>if语句之外访问。在<code>testVar</code><strong>函数的范围内,这个变量<code>foo</code>将随处可用</p><p><strong>变量与<code>let:</strong></p><p>当调用第二个函数<code>testLet</code>时,只有在<code>if语句中才能访问用<code]let声明的变量栏。因为用<code>let</code>声明的变量是<strong>块范围的</strong>(其中块是花括号之间的代码,例如<code>if{}</code>>、<code>for{}</code>、<code>function{}>/code>)</p><h2><code>让</code>变量不挂起:</h2><p><code>var</code>和<code>let</code>之间的另一个区别是,变量用<code]let</code><strong>声明,但不提升</strong>。示例是演示此行为的最佳方式:</p><p>带有<code>的变量让</code><strong>不挂起:</p><pre><code>console.log(letVar);设letVar=10;//referenceError,变量没有被提升</code></pre><p>带有<code>var</code><strong>的变量会被提升:</p><pre><code>console.log(varVar);var变量=10;//日志未定义,变量被提升</code></pre><h2>全局<code>让</code>不附加到<code>window:</h2><p>全局范围内用<code>let</code>声明的变量(这是不在函数中的代码)不会作为属性添加到全局<code>窗口</code>object上。例如(此代码在全局范围内):</p><pre><code>var bar=5;设foo=10;console.log(bar);//日志5console.log(foo);//日志10console.log(window.bar);//日志5,添加到窗口对象的变量console.log(window.foo);//日志未定义,变量未添加到窗口对象</code></pre><p><br></p><区块报价><p><strong>何时应该<code>让</code>用于<code>var</code>var</strong></p></blockquote><p>尽可能使用<code>let</code>覆盖<code>var,因为它的作用域更具体。这减少了处理大量变量时可能发生的潜在命名冲突<当您希望全局变量显式地位于<code>window</code>对象上时,可以使用code>var</code>var(如果确实需要,请务必仔细考虑)</p> https://stackoverflow.com/questions/762011/-/54674571#54674571 Daniel Viglione回答“let”和“var”的区别是什么? 丹尼尔·维格利奥内 https://stackoverflow.com/users/4501354 2019-02-13T16:07:22Z 2019-02-13T16:07:22Z <p>我想将这些关键字链接到执行上下文,因为执行上下文在所有这一切中都很重要。执行上下文有两个阶段:创建阶段和执行阶段。此外,每个执行上下文都有一个可变环境和外部环境(其词汇环境)</p><p>在执行上下文的创建阶段,var、let和const仍会将其变量存储在内存中,并在给定执行上下文的变量环境中使用未定义的值。区别在于执行阶段。如果在给变量赋值之前引用用var定义的变量,那么它就是未定义的。不会引发任何异常</p><p>但是,在声明变量之前,不能引用用let或const声明的变量。如果尝试在声明之前使用它,则在执行上下文的执行阶段将引发异常。现在,由于执行上下文的创建阶段,变量仍在内存中,但引擎不允许您使用它:</p><pre><code>函数a(){b;让b;}a();&gt;未捕获的ReferenceError:b未定义</code></pre><p>对于用var定义的变量,如果引擎在当前执行上下文的变量环境中找不到该变量,那么它将向上进入范围链(外部环境)并检查外部环境的变量环境。如果在那里找不到,它将继续搜索范围链。let和const的情况并非如此</p><p>let的第二个特点是它引入了块范围。块由花括号定义。示例包括函数块、if块、for块等。当您在块内部使用let声明变量时,该变量仅在块内部可用。事实上,每次运行块时,例如在for循环中,它都会在内存中创建一个新的变量</p><p>ES6还引入了用于声明变量的const关键字。const也是块范围的。let和const的区别在于,const变量需要使用初始值设定项声明,否则会生成错误</p><p>最后,当涉及到执行上下文时,用var定义的变量将附加到“this”对象。在全局执行上下文中,这将是浏览器中的窗口对象。对于let或const,情况并非如此</p> https://stackoverflow.com/questions/762011/-/54725672#54725672 -1 Mile Mijatović回答“let”和“var”的区别是什么? Mile Mijatović https://stackoverflow.com/users/5618326 2019-02-16T17:17:45Z 2022-03-31T14:19:07Z <p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>const name='Max';让年龄=33;var hasHobbies=true;name='Maximilian';年龄=34岁;hasHobbies=错误;const summarizeUser=(userName,userAge,userHasHobby)=&gt;{返回('名称为'+用户名+',年龄为'+用户年龄+'用户有爱好:'+用户哈斯·霍比);}console.log(summarizeUser(姓名、年龄、爱好))</代码></pre></div></div></p><p>从运行上面的代码中可以看出,当您尝试更改<code>const</code>变量时,您将<a href=“https://i.sstatic.net/sEh8Y.png“rel=”nofollow noreferrer“>获取错误:</p><区块报价><p>试图重写常量“name”</p></blockquote><p>或</p><区块报价><p>TypeError:对常量“name”的赋值无效</p></blockquote><p>但看看<code>let变量</p><p>首先我们声明<code>让age=33</code>,然后再赋值<code>age=34</code>,这是正常的;当我们尝试更改<code>let变量时没有任何错误</p> https://stackoverflow.com/questions/762011/-/55106737#55106737 卢西恩回答:“let”和“var”有什么区别? 卢西恩 https://stackoverflow.com/users/4014778 2019-03-11T16:52:45Z 2023-01-28T21:14:41Z <p>由于我目前正试图深入了解JavaScript,我将与大家分享我的简短研究,其中包括一些已经讨论过的优秀作品,以及其他一些不同角度的细节</p><p>如果我们了解<em>函数</em>和<em>块范围</em]之间的差异,那么理解<strong>var</strong>和<strong>let</strong>之间的差异会更容易</p><p>让我们考虑以下情况:</p><pre><code>(函数计时器(){对于(var i=0;i&lt;=5;i++){setTimeout(函数notime(){console.log(i);},i*1000);}})();堆栈变量环境//一个变量环境用于timer();//当计时器超时时,每个迭代的值都是相同的5.[设置超时,i][i=5]4.[设置超时,i]3.[设置超时,i]2.[setTimeout,i](设置超时,i)1.[设置超时,i]0.[设置超时,i]#################### (函数计时器(){for(设i=0;i&lt;=5;i++){setTimeout(函数notime(){console.log(i);},i*1000);}})();Stack LexicalEnvironment-每个迭代都有一个新的词汇环境5.[设置超时,i][i=5]词汇环境4.[设置超时,i][i=4]词汇环境3.[设置超时,i][i=3]词汇环境2.[设置超时,i][i=2]词汇环境1.[setTimeout,i][i=1]词汇环境0.[设置超时,i][i=0]</code></pre><p>当调用<code>timer()</code>时,将创建一个<strong>ExecutionContext</strong>,它将包含VariableEnvironment和与每个迭代相对应的所有LexicalEnvironments</p><p>还有一个更简单的例子</p><p>功能范围</p><pre><code>函数测试(){对于(var z=0;z&lt;69;z++){//待办事项}//z在循环外可见}</code></pre><p>块范围</p><pre><code>函数测试(){for(设z=0;z&lt;69;z++){//待办事项}//z未定义:(}</code></pre><p>简单地说,let和var的区别在于var是函数范围的,let是块范围的</p> https://stackoverflow.com/questions/762011/-/55737752#55737752 5 daCoda回答“let”和“var”的区别是什么? 达科达 https://stackoverflow.com/users/1903339 2019-04-18T00:49:32Z 2023-09-18T11:57:46Z <p>let vs var。这一切都与<strong>范围</strong>有关</p><p><strong>var变量是全局的</strong>,基本上可以在任何地方访问,而<strong>let变量不是全局的</strong>,只有在右括号杀死它们之前才存在</p><p>请参阅下面的示例,并注意lion(let)变量在两个console.logs中的作用是如何不同的;它超出了第二个console.log的范围</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>var cat=“cat”;let dog=“dog”;var动物=()=&gt;{var giraffe=“giraffe”;让lion=“lion”;console.log(cat)//将打印“cat”。console.log(dog)//将打印“dog”,因为dog是在此函数之外声明的(如varcat)。console.log(长颈鹿)//将打印“长颈鹿”。console.log(lion)//将打印“狮子”,因为狮子在范围内。}console.log(长颈鹿)//将打印“giraffe”,因为giraffes是一个全局变量(var)。console.log(lion)//将打印UNDEFINED,因为lion是一个“let”变量,现在已超出范围</代码></pre></div></div></p> https://stackoverflow.com/questions/762011/-/55886493#55886493 2 拉斐尔·赫斯科维奇(Rafael Herscovic)对“let”和“var”的区别是什么的回答? 拉斐尔·赫斯科维奇 https://stackoverflow.com/users/572771 2019-04-28T02:21:13Z 2019-04-28T02:21:13Z <p>我认为这些术语和大多数示例都有点令人难以接受,我个人对这种差异的主要问题是理解什么是“块”。在某种程度上,我意识到,除了<code>IF</code>语句之外,块可以是任何花括号。函数或循环的左括号<code>{</code>将定义一个新块,其中用<code>let定义的任何内容都将在同一事物(函数或循环)的右括号<code>}之后不可用;考虑到这一点,更容易理解:</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>let msg=“Hello World”;函数doWork(){//msg将可用,因为它是在这个左括号上方定义的!让朋友=0;控制台.log(消息);//但有VAR:for(var iCount2=0;iCount2&lt;5;iCount 2++){}//iCount1将在右括号后可用!控制台.log(iCount2);for(让iCount1=0;iCount1&lt;5;iCount 1++){}//iCountl在此右括号后不可用,它将返回未定义的控制台.log(iCount1);}//此括号结束后,朋友将不可用!doWork();console.log(好友)</代码></pre></div></div></p> https://stackoverflow.com/questions/762011/-/57833229#57833229 6 Piklu Dey回答“let”和“var”之间的区别是什么? Piklu Dey公司 https://stackoverflow.com/users/2467623 2019-09-07T11:25:15Z 2019-09-07T11:25:15Z <p>下面显示了“let”和“var”在范围中的不同之处:</p><pre><code>让gfoo=123;if(真){设gfoo=456;}控制台.log(gfoo);//123var hfoo=123;if(真){var hfoo=456;}console.log(hfoo);//456</code></pre><p>由<code>let定义的<code>gfoo</code>最初位于<strong>全局范围内,当我们在<code]if子句内再次声明<code>gfoo时,它的<strong><em>范围发生了更改,当给该范围内的变量赋值时,它不影响全局范围</p><p>虽然由<code>var定义的<code>hfoo</code>最初位于<strong>全局范围</strong>中,但当我们在<code]if子句中声明它时,它会考虑全局范围hfoo,尽管再次使用var来声明它。当我们重新指定它的值时,我们看到全局范围hfuo也会受到影响。这是主要区别</p> https://stackoverflow.com/questions/762011/-/59917955#59917955 19 Srikrushna回答“let”和“var”的区别是什么? 斯里克鲁什纳 https://stackoverflow.com/users/5852550 2020-01-26T11:39:21Z 2021-04-13T18:50:16Z <p>ES6引入了两个新的关键字(<strong>let</strong>和<strong>const</strong>)来替代<strong]var</strongb></p><p>当你需要块级减速时,你可以使用let和const,而不是var</p><p>下表总结了var、let和const之间的差异</p><p><a href=“https://i.sstatic.net/GBn5a.jpg“rel=”noreferrer“><img src=”https://i.sstatic.net/GBn5a.jpg“alt=”在此处输入图像描述“/></a></p> https://stackoverflow.com/questions/762011/-/61735212#61735212 112 哈桑·塞法·奥扎普(Hasan Sefa Ozalp)对“let”和“var”的区别是什么的回答? 哈桑·塞法·奥扎普 https://stackoverflow.com/users/10179445 2020-05-11T17:04:48Z 2020-05-11T17:04:48Z <h2>在最基本的术语中</h2><pre><code>for(设i=0;i&lt;5;i++){//我可以接近✔️}//我不方便</code></pre><小时>(var i=0;i&lt;5;i++)的<pre><code>{//我可以接近✔️}//我可以接近✔️</code></pre><小时><p>⚡️ 游戏沙盒&darr</p><p><a href=“https://codesandbox.io/s/let-vs-var-emzh5?fontsize=14&amp;隐藏导航=1&amp;主题=黑暗“rel=”noreferrer“><img src=”https://codesandbox.io/static/img/play-codesandbox网站.svg“alt=”编辑let vs var“></a></p> https://stackoverflow.com/questions/762011/-/64526583#64526583 6 Sarvar Nishonboyev回答“let”和“var”的区别是什么? 萨尔瓦尔·尼松博耶夫 https://stackoverflow.com/users/2490074 2020-10-25年T17:15:21Z 2020-12-30T20:05:55Z <p>我刚刚遇到一个用例,我必须使用<code>var</code>来引入新变量。这里有一个案例:</p><p>我想用动态变量名创建一个新变量</p><pre><code>让variableName='a';eval(“let”+variableName+'=10;');控制台.log(a);//这不起作用</code></pre><pre><code>var variableName='a';eval(var+variableName+'=10;');控制台.log(a);//这个有效</code></pre><p>上述代码不起作用,因为<code>eval</code>引入了一个新的代码块。使用<code>var</code>的声明将在此代码块之外声明变量,因为<code>var</code>在函数范围内声明变量</p><p>另一方面,<code>让</code>在块范围内声明变量。因此,<code>a</code>变量只在<code>eval</code>block中可见</p> https://stackoverflow.com/questions/762011/-/65308407#65308407 -2 Taib Islam Dipu回答:“let”和“var”有什么区别? 泰伯伊斯兰迪普 https://stackoverflow.com/users/12982145 2020-12-15T15:01:45Z 2020-12-15T15:01:45Z <p>2015年之前,使用<code>var</code>关键字是<strong>声明JavaScript<strong>variable</strong>的唯一方法</p><p>在ES6(JavaScript版本)之后,它允许2个新关键字<strong>let</strong>&amp<strong>常数</strong></p><p><code>让</code>=可以重新分配<code>const</code>=无法重新赋值(const来自常量,缩写为“const”)</p><p><strong>示例:</strong></p><ul><li><p>假设,声明一个国家名/您母亲的名字,<code>const</code>在这里最合适。因为很快或稍后更改国家名称或母亲名称的机会较少</p></li><li><p>您的年龄、体重、薪水、自行车速度等数据类型经常更改或需要重新分配。在这些情况下,使用<code>let</code></p></li></ul> https://stackoverflow.com/questions/762011/-/70686512#70686512 27 Ran Turner回答“let”和“var”之间的区别是什么? 兰·特纳 https://stackoverflow.com/users/7494218 2022-01-12T18:20:10Z 2023-09-23T07:21:26Z <p>解释摘自我在<a href=“https://blog.devgenius.io/how-does-heisting-in-javascript-works-80614300cb98“rel=”noreferrer“>介质</a>:</p><区块报价><p>提升是一种JavaScript机制,其中包含变量和函数声明被解析器移动到其作用域的顶部实际的代码执行由JavaScript解释器开始。所以,实际上无论在哪里声明变量或函数,它们都将无论其范围是否为全局或本地。这意味着</p><pre><code>console.log(hi);var hi=;打招呼;;</code></pre><p>实际上被解释为</p><pre><code>var hi=未定义;控制台日志(hi);hi=&quot;打招呼;;</code></pre><p>因此,正如我们刚才看到的,变量正在被提升到顶部它们的作用域,并且正在使用未定义的值进行初始化这意味着我们可以在实际操作之前分配它们的值在代码中这样声明:</p><pre><code>hi=“打招呼”console.log(hi);//打个招呼变量hi;</code></pre><p>关于函数声明,我们可以在像这样声明它们之前调用它们:</p><pre><code>sayHi();//您好!函数sayHi(){console.log('Hi');};</code></pre><p>另一方面,函数表达式没有被提升,因此我们将得到以下错误:</p><pre><code>sayHi()//输出:&quot;TypeError:sayHi不是函数var sayHi=函数(){console.log('Hi');}; </code></pre><p>ES6向JavaScript开发人员介绍了<code>let和<code>const关键字。而<code>让</code>和<code>const</code>是块范围的,不起作用范围为<code>var</code>在讨论起重行为。我们将从末尾开始,JavaScript提升<code>let和常量</p><pre><code>console.log(hi);//输出:初始化前无法访问“hi”让hi=“hi”;</code></pre><p>如上所述,<code>让</code>不允许我们使用未声明的变量,因此解释器显式输出引用错误表示之前无法访问<code>hi</code>变量初始化。如果我们更改上述<code>let,也会发生相同的错误到常量</p><pre><code>console.log(hi);//输出:初始化前无法访问“hi”const hi=“嗨”;</code></pre><p>因此,底线是,JavaScript解析器搜索变量声明和函数,并将它们提升到其范围的顶部在代码执行之前,在内存中为它们赋值如果解释器在执行代码时遇到他们将识别它们,并能够使用它们执行代码赋值。保留用<code>let</code>或<code>const</code>声明的变量在变量执行开始时未初始化用<code>var</code>声明的值被初始化为<code>undefined</p><p>我添加了这个视觉插图,以帮助更好地理解如何吊装变量和函数保存在内存中https://i.sstatic.net/7aRxL.png“rel=”noreferrer“><img src=”https://i.sstatic.net/7aRxL.png“alt=”输入图像此处显示描述“/></a></p></blockquote> https://stackoverflow.com/questions/762011/-/73671200#73671200 15 Kasun Jalitha回答“let”和“var”的区别是什么? 卡桑·贾利塔 https://stackoverflow.com/users/14073624 2022-09-10T10:48:36Z 2022-09-10T10:48:36Z <pre><code>var-->;功能范围让——&gt;块范围常量--&gt;块范围</code></pre><p><strong>var</strong></p><p>在这个代码示例中,变量<code>i</code>是使用<code>var</code>声明的。因此,它具有<em>功能范围</em>。这意味着您只能从<code>函数x内部访问<code>i。您无法从函数x外部读取</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>function x(){var i=100;控制台.log(i);//100}控制台.log(i);//错误。你不能这么做x()</代码></pre></div></div></p><p>在这个示例中,您可以看到<code>i</code>是在<code>if</code>block中声明的。但它是使用<code>var</code>声明的。因此,它获得了功能范围。这意味着您仍然可以在函数x中访问变量。因为var总是被限定为函数的范围。尽管变量<code>i</code>在<code>if</code>block中声明,但由于它使用的是<code]var</code>,因此它的作用域是父函数x</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>function x(){if(真){var i=100;}控制台.log(i);}x()</代码></pre></div></div></p><p>现在,变量<code>i</code>在<code>函数y中声明。因此,<code>i</code>的作用域是<code>函数y。您可以在函数y中访问。但不是从外部<code>函数y</code></p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>function x(){函数y(){var i=100;控制台.log(i);}y();}x()</代码></pre></div></div></p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>function x(){函数y(){var i=100;}控制台.log(i);//错误}x()</代码></pre></div></div></p><p><strong>let,常量</strong></p><p>let和const具有块作用域</p><p><code>const和<code>让</code>的行为相同。但不同的是,当您为<code>const</code>赋值时,您不能重新赋值。但您可以使用<code>let</code>重新指定值</p><p>在本例中,变量<code>i</code>在<code>if</code>block中声明。因此,只能从<code>if</code>块的内部访问它。我们无法从<code>if</code>块外部访问它。(此处,const的工作方式与let相同)</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet code js lang js prettyprint override”><code>if(true){设i=100;控制台.log(i);//输出:100}控制台.log(i);//错误</code></pre></div></div></p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>function x(){if(真){设i=100;控制台.log(i);//输出:100}控制台.log(i);//错误}x()</代码></pre></div></div></p><p>与<code>(let,const)</code>vs<code>var</code>的另一个区别是,您可以在声明变量之前访问<code]var</code>定义的变量。它将为您提供未定义的变量。但如果您使用<code>let</code>或<code>const</code>defined variable执行此操作,则会出现错误</p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>console.log(x);var x=100</代码></pre></div></div></p><p><div class=“snippet”data-lang=“js”data-hide=“false”data-console=“true”data-babel=“false”><div class=“snippet-code”><pre class=“snippet-code-js lang-js prettyprint-override”><code>console.log(x);//错误设x=100</代码></pre></div></div></p> https://stackoverflow.com/questions/762011/-/74285599#74285599 -1 用范例111回答“let”和“var”的区别是什么? 段落111 https://stackoverflow.com/users/1306645 2022-11-02T07:19:47Z 2022-11-02T07:32:48分 <p>&quot;var(变量);是函数范围和&quot;设“;是块范围的</p><p>当您想在函数中的任何位置使用变量时,可以使用var,而当您想只在该块中使用变量时可以使用它</p><p>或者,您可以一直使用var,因为您不太可能在函数中遇到范围冲突,然后不需要跟踪定义为let或var的变量</p><p>有些人建议一直使用let,但这不是我的首选,因为在许多其他编程语言中,局部变量是函数范围的,如果您使用其他语言,那么您可能会发现始终使用该模式比使用JavaScript时切换更容易。如果您一直使用let,则需要记住在更高的范围内定义变量,以便能够在“If”或“while”块之外使用它们,并且如果您决定稍后在函数级别使用它,则需要花费更多的工作来跟踪所有变量的范围,并转换其范围,例如我认为,与在同一函数中意外为变量选择两次相同的名称相比,更容易引发问题</p> https://stackoverflow.com/questions/762011/-/75841292#75841292 -1 Ali Raza回答“let”和“var”的区别是什么? 阿里·拉扎 https://stackoverflow.com/users/10115166 2023-03-25T11:08:21Z 2023-03-25T11:08:21Z <p>在JavaScript中,let和var都用于变量声明,但它们之间有一些重要的区别:</p><p><strong>范围</strong>:let和var之间的主要区别在于它们的范围。var声明是函数范围的,而let声明是块范围的</p><p><strong>提升</strong>:将var声明提升到其范围的顶部,而不提升let声明</p><p><strong>重新分配</strong>:允许您将值重新分配给变量,而var也可以重新分配,但也可以重新声明</p><p>时间死区:让声明有一个;时间死区&quot;(TDZ),这意味着如果您尝试在声明let变量之前访问它,您将得到ReferenceError</p><pre><code>函数示例(){var x=10;if(真){var x=20;//在同一范围内重新声明x设y=30;//y是if语句的块范围控制台.log(x);//输出20控制台.log(y);//输出30}控制台.log(x);//输出20(重新分配)控制台.log(y);//ReferenceError:未定义y(块范围)}</code></pre><p>总的来说,在现代JavaScript开发中,let通常比var更受欢迎,因为它的块范围和TDZ行为有助于捕捉错误并使代码更可预测</p>