简体   繁体   English

分配前的 javascript 局部变量引用

[英]javascript-local variable reference before assign

I'm learning Javascript recently.When I get into the scope chain section, the example code as following:最近在学习Javascript,进入作用域链部分,示例代码如下:

 var message = "in global"; console.log("global: message = " + message); var a = function() { var message = "inside a"; console.log("a: message = " + message); function b() { console.log("b: message = " + message); } b(); } a();
Because of curiosity, I reverse the order of line 4 and line 5, as following: 出于好奇,我把第 4 行和第 5 行的顺序颠倒了,如下:

 var message = "in global"; console.log("global: message = " + message); var a = function() { console.log("a: message = " + message); /*order reverse*/ var message = "inside a"; /*order reverse*/ function b() { console.log("b: message = " + message); } b(); } a();

I suppose the second line of output should be a: message = in global instead of a: message = undefined .我想输出的第二行应该是a: message = in global而不是a: message = undefined So why does this happen?那么为什么会发生这种情况呢?

It is because Javascript will move all the variable declaration on the top of the block.这是因为 Javascript 会将所有变量声明移动到块的顶部。 It means that your code is equivalent to this:这意味着您的代码等效于:

 var message = "in global"; console.log("global: message = " + message); var a = function() { var message; console.log("a: message = " + message); /*order reverse*/ message = "inside a"; /*order reverse*/ function b() { console.log("b: message = " + message); } b(); } a();

This issue can be avoided by using let :使用let可以避免这个问题:

 var message = "in global"; console.log("global: message = " + message); var a = function() { console.log("a: message = " + message); /*order reverse*/ let message = "inside a"; /*order reverse*/ function b() { console.log("b: message = " + message); } b(); } a();

As you can see let won't be hoisted to the top of the block, hence throwing a compiler runtime error.如您所见, let不会被提升到块的顶部,因此会引发 编译器 运行时错误。

When JavaScript compiles right before your code run, it basically makes 2 passes over your code.当 JavaScript 在您的代码运行之前编译时,它基本上会对您的代码进行 2 次传递。

First it goes through and looks at the "left hand" of the assignments, ie var message .首先,它查看并查看赋值的“左手”,即var message All of these are hoisted, which means they are virtually moved to the top of their scope, in your case the function.所有这些都被提升了,这意味着它们实际上被移动到了它们的范围的顶部,在你的例子中是函数。

Then it goes through and executes your code, and this time looks at the "right hand" side of assignments, ie = "inside a" .然后它遍历并执行您的代码,这次查看赋值的“右手”侧,即= "inside a"

Because of that, when it does your console.log , it already knows about the a you have created inside of the function .因此,当它执行您的console.log ,它已经知道您在函数内部创建的a Since this shadows the global a variable, the current value is "undefined" since it has not been set to "inside a" yet by the time you are doing your console log.由于这会影响全局a变量,当前值是“未定义”,因为在您执行控制台日志时它尚未设置为“inside a”。

It's naturally confusing, which is why shadowing is discouraged.这自然会令人困惑,这就是不鼓励使用阴影的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM