2.
最近正在系统学习JS,等我学成归来为你解惑,也许2,3年。等我兄弟!
小米8(白)
3.
@老虎会游泳,
我的猜想是报重复定义的错误,不是报未定义变量的错误,但是却没有报错,还直接出结果了,我只是不知道为什么是这个结果。对了,es6是默认严格模式
红米K30 Pro 变焦版
4.
@艾木友尔尔巴,那我倾向于你去学一门正常的语言,c++,java,go都行
红米K30 Pro 变焦版
5.
@老虎会游泳,疑点在于两个图只是把let改成var,但是结果却不同了,如果结合知乎的文章做参考,那个只能解释var的情况,大概意思是这个。
红米K30 Pro 变焦版
8.
@Curtion,只有ES6模块才会处于自动严格模式。但是你的文件只是一个js,并不是ES6模块,所以并没有自动严格模式。
9.
@Curtion,很遗憾,node的严格模式依然不会对此报错。

我发现只有在浏览器内逐条执行语句时,它才会报重复定义错误。如果一次性执行,就不会报错。


10.
@Curtion,我觉得问题的关键是,在js中这到底是什么:
{
xxx;
}
代码块?
函数定义?
闭包?
对象?
如果它只是产生了一个对象,并没有立即执行里面的代码,那么当然不会报错。
而在浏览器逐行执行的时候,就会对每行的返回结果进行求值(因为浏览器要打印返回结果),所以才会触发报错。
11.
看起来它确实是立即执行的代码块。
那么let
的作用域问题就令人迷惑了。

12.
@老虎会游泳,@Curtion,
主要还是函数变量提升和let块级作用域的问题吧
我来完善一下等价代码 就比较容易看了:
let a = 0;
{
var A = undefined;
A = 1;
function 1(){};
}
console.log(a);
var a = undefined;
var a = 0;
//{
a = 1;
function 1(){};
//}
console.log(a);

小米MIX2s(白)
13.
@Curtion,@水木易安,原来如此,如果把function a() {};
删掉,结果就是1了。

14.
@水木易安,@Curtion,实际上最有趣的一点在于,以下代码输出1
:
{
a = 1;
function a() {};
console.log(a);
};
所以它实际上相当于:
{
function a() {};
a = 1;
console.log(a);
};
执行时似乎发生了“函数提升”,函数定义被放在了最前面。


15.
@老虎会游泳,是的.
js存在变量提升和函数提升
经过你的提醒 我发现我的function a(){}理解错了 似乎的确是全部提升了
而我在浏览器debug的时候发现这个:

小米MIX2s(白)
16.
@水木易安,@老虎会游泳,
{
a = 1;
function a() {};
}
实际上是这样的:
var a1 = undefined
{
let a2 = funcrtion a() {}
a2 = a
a1 = a2
}
a1和a2是方便理解的东西,在实际上它们都是a,但是程序处理时是当成两个东西来处理的。
举个例子:
var a = 0;
{
a = 123;
function a() {}
a = 456;
console.log(a);
}
console.log(a);
这段代码实际上输出的是456,123 ,如果是@水木易安,的理解,那么应该输出456,456才对
红米K30 Pro 变焦版
18.
@水木易安,@老虎会游泳, 这里有一个回答: https://stackoverflow.com/questions/31419897/what-are-the-precise-semantics-of-block-level-functions-in-es6) 再结合知乎的文章,我推测
var a1 = undefined
{
let a2 = funcrtion a() {}
a2 = a
a1 = a2
}
这段代码中的 a1就是VariableEnvironment(变量环境),a2就是LexicalEnvironment(词法环境)。这样理解那这段代码逻辑是可以说清楚的,但是当第一行的var变成let后,两个a都在LexicalEnvironment(词法环境)了,我的理解应该会报错,但是实际上直接输出了0
红米K30 Pro 变焦版