Javascript ES6'let'和'var' - 函数内部的意外行为,参数名称匹配重新声明的变量

Posted

技术标签:

【中文标题】Javascript ES6\'let\'和\'var\' - 函数内部的意外行为,参数名称匹配重新声明的变量【英文标题】:Javascript ES6 'let' and 'var' - unexpected behavior inside function with argument name matching redeclared variableJavascript ES6'let'和'var' - 函数内部的意外行为,参数名称匹配重新声明的变量 【发布时间】:2019-10-17 00:09:42 【问题描述】:

请注意,这不是现有 var 与 let 范围的重复。我知道 var 和 let 声明和差异的范围。

但在以下情况下,我无法证明我对 letvar 差异的理解是合理的。

在下面的代码中,函数foo 接受名为“x”的参数,该参数具有隐含的let 范围 - 因为我无法在该函数内使用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' 有效,但在使用 'var' 在全局范围内重新声明 'y' 时会引发错误

【问题讨论】:

What's the difference between using "let" and "var"?的可能重复 @code maniac,我不是在问 'let' 和 'var' 之间的基本区别,它们在函数内部和外部函数重新声明的行为令人困惑,内部函数允许重新声明使用 var 的参数,但外部函数是它抛出错误。请解释或指向我可以清楚理解的文档或示例 简单的拇指规则在一个范围内,如果你用let定义了任何变量,你不能重新定义它,不要与函数参数混淆,它们的行为就像用var定义的var一样知道 @CodeManiac,它在函数参数中的行为不像var,而是像let,这可以通过在函数内注释掉var x = 30;和取消注释let x = 400;来测试foo,它会引发错误,因为您无法重新声明已使用 let 声明的变量 Cannot use let to define a variable with the same name of function's parameter的可能重复 【参考方案1】:

var 声明语法是该语言的原始语法,并且具有相当宽松的规则。 letconst 声明更新更严格。你不能用letconst 重新声明变量,无论它们最初是如何声明的。而如果一个变量用letconst声明,后面的var声明也是错误的。

通过letconst 的声明将不允许在声明之前引用变量;这就是为什么您会收到第一个示例中提到的错误。换句话说,

console.log(x);
let x = 0;

是一个错误,因为在声明之前引用了x

【讨论】:

'let' 不会提升变量,但在函数中它已经在参数中隐式声明为 'let x' 并且期望在重新声明 x 时应该抛出错误内部函数,但它工作正常,函数内部没有错误,但在函数外部抛出错误。想知道这种行为在函数和全局中有何不同 @ChandreGowda 我真的不明白你的意思。 let 确实将声明提升到封闭块,但声明之前的引用是错误的。 我说“变量提升”只发生在使用“var”声明的变量上,因此您将能够在声明之前访问/打印它,在您的示例中,您使用“let”声明了 x 并且由于'let'变量没有被提升,它不会引用访问并因此抛出错误。 @ChandreGowda 提升只发生在var 上是不正确的。 带有letconst 的变量声明被提升到封闭块,但声明之前的引用是不允许的。如果您尝试重新声明此类变量,那就很清楚了。

以上是关于Javascript ES6'let'和'var' - 函数内部的意外行为,参数名称匹配重新声明的变量的主要内容,如果未能解决你的问题,请参考以下文章

javascript ES6 新特性之 let

JavaScript中的 let 和 var

JavaScript中的 let 和 var

JavaScript ES6 - let 与 const 使用方及与var对比

JavaScript ES6 - let 与 const 使用方及与var对比

JavaScript学习笔记 -- ES6学习 let 和const