我不明白为什么在函数内部声明变量时,行为为何如此奇怪。示例:
function first() {
let a = b = c = 10;
var d = 20;
second();
}
function second() {
alert(b + ", " + c); //shows "10, 10"
alert(a); //reference error
alert(d); //reference error
}
这是因为您实际上是在说:
c = 10;
b = c;
let a = b;
而不是您认为的意思,是:
let a = 10;
let b = 10;
let c = 10;
您会注意到,无论您将多少个变量添加到链中,它只会是导致错误的第一个(a)。
这是因为“ let”将变量的作用域限定为声明变量的块(或“局部”,或多或少的意思是“在方括号中”)。
如果声明不带“ let”的变量,它将在全局范围内定义变量。
因此,在设置变量的函数中,所有值都为10(如果放置断点,则可以在调试器中看到此值)。如果您在第一个函数中为a,b,c放置一个控制台日志,一切都很好。
但是一旦您离开该功能,第一个(a)-再一次,请记住,从技术上讲,按照分配的顺序,它是最后一个-“消失”(同样,您可以看到如果您在第二个函数中设置了断点,则可以在调试器中进行操作,但是其他两个(或添加的数目)仍然可用。
这是因为,“ let”仅适用于(因此仅在本地范围内)链中的第一个变量-同样,从技术上讲,它是最后一个要声明并分配值的变量。从技术上讲,其余的都没有在前面。因此,它们在技术上是全局声明的(即在全局对象上),这就是它们出现在第二个函数中的原因。
[尝试一下:删除“ let”关键字。您所有的var现在都可以使用了。
“ var”具有类似的局部作用,但在变量“提升”方式上有所不同,这是您应该绝对了解的,但与您的问题没有直接关系。
(顺便说一句,这个问题将困扰足够的专业JS开发人员,使其成为一个好人。]
[强烈建议您花时间在JS中声明变量的方式上有所不同:不带关键字,带“ let”和“ var”。
在功能first()
中,无需使用b
或c
即可即时创建变量var
和let
。
let a = b = c = 10; // b and c are created on the fly
与...不同
let a = 10, b = 10, c = 10; // b and c are created using let (note the ,)
它们成为隐式全局。这就是为什么它们在second()
在执行分配时,将值分配给未声明的变量会隐式将其创建为全局变量(它成为全局对象的属性)。
为避免这种情况,您可以使用"use strict"
,当一个人使用一个未声明的变量时会出现错误
"use strict"; // <-------------- check this
function first() {
/*
* With "use strict" c is not defined.
* (Neither is b, but since the line will be executed from right to left,
* the variable c will cause the error and the script will stop)
* Without, b and c become globals, and then are accessible in other functions
*/
let a = b = c = 10;
var d = 20;
second();
}
function second() {
console.log(b + ", " + c); //reference error
console.log(a); //reference error
console.log(d); //reference error
}
first();
在称奇事物之前先让我们了解一些基础知识:
var和let都用于javascript中的变量声明例如
var one = 1;
let two = 2;
也可以在不使用var或let的情况下声明变量例如
three = 3;
现在上述方法之间的区别在于:
var是函数范围的
和
让块作用域。
while
不使用var / let关键字声明的变量的范围将成为global,而不管声明在哪里。可以从网页的任何位置访问全局变量。(不建议使用,因为可能会意外修改全局变量。)
现在根据这些概念,让我们看一下所讨论的代码:
function first() {
let a = b = c = 10;
/* Above line means:
let a=10; //block scope
b=10; //global scope
c=10; //global scope
*/
var d = 20; //function scope
second();
}
function second() {
alert(b + ", " + c); //shows "10, 10" //accessible because of global scope
alert(a); //error not accessible because block scope has ended
alert(d); //error not accessible because function scope has ended
}
使用let
关键字的变量应仅在块范围内可用,而在外部函数中不可用...
您以这种方式声明的每个变量都没有使用let
或var
。您在变量声明中缺少逗号。
建议不推荐声明不带var
关键字的变量。它可能会意外覆盖现有的全局变量。不使用关键字var
声明的变量的范围将变为全局变量,而与声明的位置无关。可以从网页的任何位置访问全局变量。
function first() {
let a = 10;
let b = 10;
let c = 10;
var d = 20;
second();
}
function second() {
console.log(b + ", " + c); //shows "10, 10"
console.log(a); //reference error
console.log(d); //reference error
}
first();