如何解决使用“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 中错误的主要来源之一。
查看此示例:
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]();
调用时都会输出到控制台,因为匿名函数绑定到同一个变量。
人们必须创建立即调用的函数来从循环中捕获正确的值,但这也很麻烦。
Hoisting
虽然用var
关键字声明的变量被hoisted(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();
创建全局对象属性
在顶层let
,与 不同var
,不会在全局对象上创建属性:
var foo = "Foo"; // globally scoped
let bar = "Bar"; // not allowed to be globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
Redeclaration
在严格模式下,var
将让您在同一范围内重新声明相同的变量,同时let
引发 SyntaxError。
'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
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。