Javascript ES6 'let' 和 'var' - 参数名称与重新声明的变量匹配的函数内部的意外行为
Javascript ES6 'let' and 'var' - unexpected behavior inside function with argument name matching redeclared variable
请注意,这不是现有 var 与 let 作用域的副本。我知道 var 和 let 声明的范围和区别。
但在下面的情况下,我无法证明我对 let
和 var
差异的理解。
在下面的代码中,函数 foo
接受具有隐式 let
范围的名称 'x' 的参数 - 因为我无法在其中使用 let
重新声明相同的变量名称函数(取消注释函数中的最后一行 foo
将抛出 JS 错误)
"use strict";
function foo(x) {
console.log('Inside function x:', x);
var x = 30; // 'x' redeclared overwriting argument/parameter 'x'
console.log('Redeclared x:', x);
// let x = 400; // uncommenting this line throws error even if you remove 'var x = 30;'
}
foo(100);
// global
let y = 100;
console.log('y:', y);
// var y = 300;
执行上面两行注释掉的代码效果很好,你可以看到输出为:
Inside function x: 100 index.js:4
Redeclared x: 30 index.js:6
y: 100 index.js:13
取消注释最后一行 // var y = 300;
将引发错误。
问题是:为什么在函数 foo
中使用“var
”重新声明 'x' 有效,但在 'y' 时抛出错误使用“var
”
在全局范围内重新声明
var
声明语法是该语言的原创语法,具有相当宽松的规则。 let
和 const
声明更新更严格。你不能 re-declare 带有 let
或 const
的变量,无论它们最初是如何声明的。如果用 let
或 const
声明变量,则随后的 var
声明也是错误的。
通过 let
和 const
的声明将不允许在声明之前引用变量;这就是为什么您会收到第一个示例中提到的错误的原因。也就是说,
console.log(x);
let x = 0;
是一个错误,因为在声明之前引用了x
。
请注意,这不是现有 var 与 let 作用域的副本。我知道 var 和 let 声明的范围和区别。
但在下面的情况下,我无法证明我对 let
和 var
差异的理解。
在下面的代码中,函数 foo
接受具有隐式 let
范围的名称 'x' 的参数 - 因为我无法在其中使用 let
重新声明相同的变量名称函数(取消注释函数中的最后一行 foo
将抛出 JS 错误)
"use strict";
function foo(x) {
console.log('Inside function x:', x);
var x = 30; // 'x' redeclared overwriting argument/parameter 'x'
console.log('Redeclared x:', x);
// let x = 400; // uncommenting this line throws error even if you remove 'var x = 30;'
}
foo(100);
// global
let y = 100;
console.log('y:', y);
// var y = 300;
执行上面两行注释掉的代码效果很好,你可以看到输出为:
Inside function x: 100 index.js:4
Redeclared x: 30 index.js:6
y: 100 index.js:13
取消注释最后一行 // var y = 300;
将引发错误。
问题是:为什么在函数 foo
中使用“var
”重新声明 'x' 有效,但在 'y' 时抛出错误使用“var
”
var
声明语法是该语言的原创语法,具有相当宽松的规则。 let
和 const
声明更新更严格。你不能 re-declare 带有 let
或 const
的变量,无论它们最初是如何声明的。如果用 let
或 const
声明变量,则随后的 var
声明也是错误的。
通过 let
和 const
的声明将不允许在声明之前引用变量;这就是为什么您会收到第一个示例中提到的错误的原因。也就是说,
console.log(x);
let x = 0;
是一个错误,因为在声明之前引用了x
。