以下代码将输出“1”。但是,关键字“let”不应该使x不是全局变量,因此它对das()不可见吗? let应该将变量的范围限制为仅声明它们的块,但是在这里,我看到内部函数可以访问“let”变量,即使x被声明在其范围之外。怎么可能?
function letTest() {
function das () {
console.log(x);
// How does this function have access to a let variable declared outside its scope?
}
let x = 1;
das();
}
letTest();
答案 0 :(得分:3)
这是一种思考let
如何运作的方式:
let
。{
。let
找到相应的}
。这为您提供了变量可见的范围。如果函数定义出现在该范围内,则很好;该变量对该函数中的代码可见。
现在, little 有点奇怪的是,在你的例子中,变量看起来像它在声明之前在范围中使用。这就是参考在声明之前出现的事实变得更有趣。
通常,如果范围中的代码在let
实际发生之前引用了let
- 声明的变量,那就是错误。但是,这是一个运行时的东西,而不是语法的东西。在您的情况下,在运行时,let
将在调用嵌套函数时“发生”。
答案 1 :(得分:1)
let
将变量的范围限制为当前块(在这种情况下,与letTest
函数相同)。
das
函数在该范围内声明,因此它可以访问该范围内的任何内容(包括x
)。
答案 2 :(得分:0)
问题是你没有改变x的值,在你的情况下,你只是将它记录到控制台,它们都嵌套在一个范围内,不限制内部函数,所以你的结果是预期的。 / p>
现在,如果你做了类似的事情
function letTest() {
function das () {
console.log(x);
// How does this function have access to a let variable declared outside its scope?
}
let x = 1;
function change(){
x = x + 1;
}
change();
}
letTest();
现在您正在尝试更改x的值,编译器会抱怨。
答案 3 :(得分:0)
如此处所述:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let它在块范围内提供访问权限。由于您的das()
执行和x声明位于同一块范围内,因此它将具有访问权限。
一个很好的例子是在下面的switch案例中,在案例1中使用var x = 'x'
会导致它附加到函数作用域并且可以在console.log()中访问,但是当尝试引用bar变量进行日志记录时它抛出一个引用异常。但仍然适用于默认情况。
const example = (foo) => {
switch(foo) {
case 0:
break;
case 1:
let bar = 'bar';
var x = 'x';
break;
default:
console.log(bar);
break;
}
console.log(x);
console.log(bar);
}
example(1);
答案 4 :(得分:0)
该函数在与x
相同的块中声明,因此函数内的代码可以访问x
。
如果您不想要,可以随时添加新块:
function letTest() {
function das () {
console.log(x); // ReferenceError
}
{ // New block
let x = 1;
das();
}
}
letTest();

答案 5 :(得分:0)
@GTS Joe,
let x
是letTest()
上下文的本地,因此das()
只是访问其x
变量。那里没什么奇怪的。所以,'不' - 它没有变得全球化。
无论嵌套变量调用的 context 有多深,总有一个查找 JS原则 < / strong>,这将会在失败的 环顾 后继续,并将继续在全局范围内查找此变量名称,并且只有这样 - 当没有任何内容时发现 - 它会引起参考错误。
而且 - 只是因为没有看下面 JS原则 - 所谓的闭包是可能的。
答案 6 :(得分:-1)
它不在范围之外。 x
和 das()
定义在同一个块作用域中。该块中的任何其他内容都可以访问 x
。这包括任何嵌套函数、for
循环、while
循环和 if
条件。这包括 elseif
条件中的 else
和 if
。