我在多个网站(比如w3schools)上读到,提升是“将所有声明移到当前范围顶部的行为”。
对于let和const,变量是悬挂的,但没有初始化。
我理解为什么下面的代码不能工作,因为name对我们来说没有价值。
console.log(name);
let name = "hi";
但是为什么我们不能在name的实际声明之前给它赋值,即使name已经被声明(提升)?
name = "hi";
let name;
console.log(name);
上述代码不与以下代码相同吗?
let name;
name = "hi";
console.log(name);
发布于 2021-07-04 09:21:55
因为它们的明确设计是不允许这样做的,因为这通常是一个编程错误。
let和const都是悬挂的,但这只是绑定的声明而已。(松散地说,"binding“意为”变量“或常量或parameter...things,其名称用于保存值。)绑定直到稍后在逐步执行代码时到达let或const语句时才初始化。您不能使用未初始化的绑定(以任何方式),这也是您获得错误的原因。
相反,对于var,声明和初始化都是悬挂的;var绑定是用值undefined初始化的。如果var (var a = 42)上有一个初始化值,那么稍后在逐步执行代码时到达var语句时,该部分将被视为简单赋值(a = 42)。对于let和const,它不仅仅是简单的赋值,而是绑定的初始化,允许使用它。
下面是一个具体的例子,说明let如何提升声明,而不是初始化,以及为什么它有助于防止编程错误:
let a = 1;
function foo() {
a = 2; // <=== Which `a` should be assigned to?
console.log(a);
// code
// code
// code
// code
// code
// code
// code
// code
let a = 3;
console.log(a);
}
foo();
在该代码中,foo顶部的赋值似乎应该分配给外部a,因为(据我们所知,自上而下阅读)范围中没有其他a。但确实存在,因为位于let底部的foo已被悬挂。执行分配时会出现错误,因为内部a没有初始化。
相反,对于var,没有错误,但是很容易混淆在foo顶部分配了哪个a。
在注释中,您表示仍然不理解声明绑定而不是初始化绑定意味着什么。我认为“初始化”的两个(轻微)含义在这里让你感到困惑(当我进入这个话题时,它们让我感到困惑),所以让我们稍微修改一下术语。
绑定有一个与它们相关联的标志,说明是否可以使用它们。让我们称它为usable标志:usable = true表示可以使用绑定,usable = false表示不能使用。
创建脚本的执行上下文时的
1. Bindings for all top level declarations within it are created:
- The `let a` part of `let a = 1;` creates a binding called `a` with its `usable` flag set to `false` (can't be used yet).
- The function declaration (`function foo() { }`) creates a binding called `foo` with its `usable` flag set to `true` (can b eused) and its value set to `undefined`.1. Function declarations within the context are processed by creating the functions they define and assigning them to the binding. So `foo` gets its function value.当在逐步执行代码过程中遇到
usable标志设置为true (可以使用),并将a的值设置为true。当调用
。
1. A binding called `a` is created by `let a = 3;` with its `usable` flag set to `false` (can't be used yet).当在代码的逐步执行中到达
a解析为内部a绑定( foo中的绑定,由let a = 3;声明),但是绑定的usable标志是false,因此尝试使用它会引发错误。< code >H 257G 258a = 2;语句,所以没有抛出错误,然后当逐步执行代码到达let a = 3;语句时,它将做两件事:将usable标志设置为true (可以使用),并将a的值设置为3.。
下面是带有一些注释的foo更新:
function foo() {
// The local `a` is created but marked `usable` = `false`
a = 2; // <=== Throws error because `a`'s `usable` is `false`
console.log(a);
let a = 3; // <=== If there weren't an error above, this would set
// `usable` to `true` and the value of `a` to `3`
console.log(a);
}“我认为”初始化“的两个(略)含义在这里混淆了你。”我指的两个意思是:
usable设置为true)和separately它们是不同的东西。
https://stackoverflow.com/questions/68243230
复制相似问题