内容来自 DOC[ https://q.houxu6.top/?s="let" 和 "var" 的区别是什么?](https://q.houxu6.top/?s="let" 和 "var" 的区别是什么?)
ECMAScript 6引入了let
语句。
我听说它被描述为一个局部变量,但我仍然不太清楚它与var关键字的行为有什么不同。
它们之间的区别是什么?什么时候应该使用let
代替var
?
作用域规则
主要区别在于作用域规则。var
关键字声明的变量作用域为函数体(因此为函数作用域),而let
变量作用域为由{ }
表示的立即包围块(因此为块作用域)。
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();
let
关键字被引入语言的原因是函数作用域令人困惑,并且是JavaScript中的主要错误来源之一。
看看这个来自Stack Overflow另一个问题的示例:
var funcs = [];
// 让我们创建3个函数
for (var i = 0; i < 3; i++) {
// 并将它们存储在funcs中
funcs[i] = function() {
// 每个都应该记录其值。
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// 现在让我们运行每个函数以查看
funcs[j]();
}
每次调用funcs[j]();
时,My value: 3
都会被输出到控制台,因为匿名函数绑定到了相同的变量。
人们不得不创建立即调用的函数来捕获循环中的正确值,但这也很棘手。
提升
虽然使用var
关键字声明的变量会被提升(在代码运行之前用undefined
初始化),这意味着它们在包围范围内可访问,直到它们的定义被评估:
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();
创建全局对象属性
在顶层,与var
不同,let
不会在全局对象上创建属性:
var foo = "Foo"; // 全局作用域
let bar = "Bar"; // 不允许全局作用域
console.log(window.foo); // Foo
console.log(window.bar); // undefined
重新声明
在严格模式下,var
将允许您在同一作用域中重新声明相同的变量,而let
会引发语法错误。
'use strict';
var foo = "foo1";
var foo = "foo2"; // 没有问题,'foo1'被替换为'foo2'。
let bar = "bar1";
let bar = "bar2"; // 语法错误:标识符'bar'已经被声明过了
标签:console,log,区别,作用域,let,var,foo
From: https://www.cnblogs.com/xiaomandujia/p/17750142.html