.jpg)
网友问题:
ECMAScript 6 引入了该语句。let
我听说它被描述为局部变量,但我仍然不太确定它的行为与 var 关键字有何不同。
有什么区别?何时应使用代替 ?letvar

网友回答:
let也可用于避免闭包问题。它绑定新值,而不是保留旧引用,如以下示例所示。
for(var i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
上面的代码演示了一个经典的 JavaScript 闭包问题。对变量的引用存储在单击处理程序闭包中,而不是 的实际值中。ii
每个单击处理程序都将引用相同的对象,因为只有一个计数器对象可容纳 6,因此每次单击都会获得 <> 个。
一般解决方法是将其包装在匿名函数中并作为参数传递。现在也可以通过使用下面的代码所示来避免此类问题。iletvar
(在Chrome和Firefox 50中测试)
for(let i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>

网友回答:
主要区别在于范围规则。关键字声明的变量的作用域为直接函数体(因此为函数作用域),而变量的作用域为由(因此称为块作用域)表示的直接封闭块。varlet{ }
function run() {
var foo = "Foo";
let bar = "Bar";
console.log(foo, bar); // Foo Bar
{
var moo = "Mooo"
let baz = "Bazz";
console.log(moo, baz); // Mooo Bazz
}
console.log(moo); // Mooo
console.log(baz); // ReferenceError
}
run();
关键字被引入语言的原因是函数作用域令人困惑,并且是JavaScript中错误的主要来源之一。let
看看另一个堆栈溢出问题中的例子:
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
My value: 3每次调用时都输出到控制台,因为匿名函数绑定到同一变量。funcs[j]();
人们必须立即创建调用的函数来从循环中捕获正确的值,但这也很麻烦。
虽然用关键字声明的变量被提升(在代码运行之前初始化),这意味着即使在声明它们之前,它们也可以在它们的封闭范围内访问:varundefined
function run() {
console.log(foo); // undefined
var foo = "Foo";
console.log(foo); // Foo
}
run();
let在计算变量的定义之前,不会初始化变量。在初始化之前访问它们会产生 .该变量被称为从块开始到初始化被处理的“时间死区”。ReferenceError
function checkHoisting() {
console.log(foo); // ReferenceError
let foo = "Foo";
console.log(foo); // Foo
}
checkHoisting();
在顶层,与 不同,不会在全局对象上创建属性:letvar
var foo = "Foo"; // globally scoped
let bar = "Bar"; // not allowed to be globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
在严格模式下,将允许您在同一作用域中重新声明相同的变量,同时引发语法错误。varlet
'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.
let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared

网友回答:
letvarvar(*)let(**)若要了解差异,请考虑以下代码:
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
在这里,我们可以看到我们的变量只在第一个 for 循环中是已知的,而不是在之前和之后。然而,我们的变量在整个函数中是已知的。ji
此外,请考虑块范围的变量在声明之前是未知的,因为它们没有被提升。您也不允许在同一块中重新声明相同的块范围变量。这使得块范围的变量比全局或功能范围的变量更不容易出错,全局或功能范围的变量是吊装的,在多个声明的情况下不会产生任何错误。
let有些人会争辩说,将来我们只会使用 let 语句,而 var 语句将变得过时。JavaScript 大师 Kyle Simpson 写了一篇非常详细的文章,解释了为什么他认为情况并非如此。
然而,今天,情况绝对不是这样。事实上,我们实际上需要问问自己使用该语句是否安全。该问题的答案取决于您的环境:let
如果您正在编写服务器端 JavaScript 代码 (Node.js),则可以安全地使用该语句。let
如果您正在编写客户端 JavaScript 代码并使用基于浏览器的转译器(如 Traceur 或 babel-standalone),则可以安全地使用该语句,但是您的代码在性能方面可能不是最佳的。let
如果您正在编写客户端 JavaScript 代码并使用基于 Node 的转译器(如 traceur shell 脚本或 Babel),则可以安全地使用该语句。而且,由于您的浏览器只会知道转译的代码,因此性能缺陷应该受到限制。let
如果您正在编写客户端 JavaScript 代码并且不使用转译器,则需要考虑浏览器支持。
仍然有一些浏览器根本不支持:let
有关在您阅读此答案时哪些浏览器支持该声明的最新概述,请参阅此“我可以使用”页面。let
(*) 全局和功能范围的变量可以在声明之前进行初始化和使用,因为 JavaScript 变量是被提升的。这意味着声明始终移动到范围的顶部。
(**)块范围的变量不被提升
模板简介:该模板名称为【let”和“var”有什么区别?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【JavaScript】栏目查找您需要的精美模板。