Javascript 让变量作用域
下面的代码将输出“1”。但是,关键字“let”不应该使x成为全局变量,从而使它对das()不可见吗?let应该将变量的作用域限制在它们声明的块上,但是在这里,我看到一个内部函数可以访问一个“let”变量,即使x声明在它的作用域之外。这怎么可能Javascript 让变量作用域,javascript,variables,let,Javascript,Variables,Let,下面的代码将输出“1”。但是,关键字“let”不应该使x成为全局变量,从而使它对das()不可见吗?let应该将变量的作用域限制在它们声明的块上,但是在这里,我看到一个内部函数可以访问一个“let”变量,即使x声明在它的作用域之外。这怎么可能 函数测试(){ 函数das(){ 控制台日志(x); //此函数如何访问在其作用域之外声明的let变量? } 设x=1; das(); } letTest()let将变量的范围限制到当前块(在这种情况下,与letTest函数相同) das函数在该范围内声
函数测试(){
函数das(){
控制台日志(x);
//此函数如何访问在其作用域之外声明的let变量?
}
设x=1;
das();
}
letTest()
let
将变量的范围限制到当前块(在这种情况下,与letTest
函数相同)
das
函数在该范围内声明,因此它可以访问该范围内的任何内容(包括x
)。下面是一种思考让工作的方法:
从开始,让
在相同的嵌套级别,通过源代码进行备份/备份,找到第一个{
现在,让我们从中找到相应的}
这为您提供了变量可见的范围。如果函数定义出现在该范围内,则为罚款;该变量对该函数中的代码可见
现在,有点奇怪的是,在您的示例中,变量看起来像是在声明之前在作用域中使用的。这就是引用出现在声明之前这一事实变得更加有趣的地方
通常,如果作用域中的代码在let
实际发生之前引用了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;
function change(){
x = x + 1;
}
change();
}
letTest();
现在您正试图更改x的值,编译器会抱怨 如本文所述:它提供块范围内的访问。由于您的das()
执行和x声明在同一块范围内,它将具有访问权限
下面的开关示例是一个很好的例子,在案例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);
函数在与x
相同的块中声明,因此函数中的代码可以访问x
如果您不想这样做,则始终可以添加新块:
函数测试(){
函数das(){
console.log(x);//引用错误
}
{//新区块
设x=1;
das();
}
}
letTest()代码>@GTS-Joe
let x
是letTest()
上下文的本地变量,因此das()
只是访问其x
变量。那里没有发生什么奇怪的事。所以,“不”——它并没有变得全球化
无论变量调用的上下文嵌套得有多深,总会有一个查找JS原则,它将遵循失败的查找,并在全局范围内继续查找此变量名称,只有到那时,当什么都没有找到时,它才会导致引用错误
而这仅仅是因为JS原则下没有任何外观,所以所谓的闭包是可能的。它不在范围之外x
和das()
在同一块范围内定义。该块中的任何其他内容都可以访问x
。它包括任何嵌套函数、for
循环、while
循环和if
条件。这包括elseif
和else
,它们在if
条件中。我认为这是因为das
在x
中定义的块中。。仅在2个块内,但其中一个块也围绕着let
,因此x
不必是全局的,以便在嵌套函数中可见;它必须在局部范围内或某些外部范围内。let
声明不局限于局部范围的可见性;它是本地作用域加上任何嵌套作用域。换句话说,嵌套函数中的代码是包含let
的块的一部分。也许我错了,但我认为这与提升无关。所以“let”限制外部作用域,而不是内部作用域?@GTSJoe我刚刚对另一个答案发表了评论。没有“内部作用域”这样的东西。@GTSJoe换句话说,嵌套函数体的{}
与作用域中出现的{}
循环的{}
没有区别。@GTSJoe还可以看到我的更新;我意识到我在使用let
时忽略了一些细微差别。