Is variable initialization also hoisted in JavaScript

不打扰是莪最后的温柔 提交于 2020-01-24 19:05:24

问题


JavaScript Hoisting confuses me. Is variable initialization hoisted ? i think it is hoisted because we access variable before we declare and initialize it

console.log(a);
var a = 4;
undefined
undefined

undefined shows that variable a is declare before code execute this is because of hoisting.

if i'm wrong please correct me.


回答1:


the way this works is that the variable is accessible in the entire program, see the following:

'a' is undefined because it is not declared in the program,

however when I declare a it is now accessible in the entire program.

if I set the value of a, that only occurs AFTER the console log, the order of operations is still intact the only thing that is hoisted is the declaration.

lol I forgot the parenthesis around the 'a' on that last one, not too sure on why quokka still had the expected output, quokka for the win for reading my mind haha




回答2:


TLDR

In JavaScript, both variable and function declarations are hoisted.

Initialization is not.


Hoisting means that - regardless of the lexical position of declaration - the identifier is semantically present from the very start of the enclosing code region (function or block).

This means identifiers (ie. variable names) are semantically present before the line of code at which they are declared - if only to guarantee confusion does not occur between identifiers with the same name.

Note that a hoisted identifier might not (eg if declared using let) be available for access by the developer until the declaration of the variable has been evaluated. ie. some time after the function or block has started executing. The formal name for this period is "Temporal Dead Zone".

In JavaScript, both variable and function declarations are hoisted.

Initialization is not.

For variables declared with var, the effect is that the declaration can be imagined to be at the very top of the enclosing function, regardless of the lexical (ie. in the code) position of the declaration.

For everything else in strict mode code (function, function*, let, const , class) the effect is that declarations can be imagined to be at the very top of the enclosing block (which might or might not be a function), regardless of their lexical position of declaration.

Non-strict code has a separate, more complicated set of rules for function statements enclosed within blocks. See also.

In the case of variables declared using var, the variable itself (with a default value of undefined) is available for assignment and dereferencing (reading its value) from the top of the enclosing execution context.

Hoisted var declarations are automatically initialized with undefined.

For everything else the runtime is aware of the identifier from the top of the enclosing block, but it is not available for assignment or dereferencing until the flow of execution has moved passed the point of lexical declaration. ie. that the Temporal Dead Zone has passed.

Hoisted function/function* declarations are immediately initialized with the hoisted function.

Note that in JavaScript, the algorithm for initializing execution contexts (stack frames) handles function declarations last, meaning that function declarations appear to be hoisted "higher" than var declarations.

This means that if a function declaration and a var with the same identifier are both declared within the same function, the identifier will be associated with the function (and not the var) at the start of execution of the enclosing function.

For let, const and class the identifier will not be initialized until control has moved past the lexical declaration of the variable.

These let, const and class declaration types were added to the language much later in its life (ES 2015).

The language designers chose this new behavior to make JavaScript easier to understand and to avoid subtle bugs that permitting assignment and dereferencing before the lexical point of declaration can introduce.

For this reason, there used to be a best-practice in JavaScript that said variables should be declared at the very top of their enclosing functions.

So in your example code:

1  console.log(a);
2  var a = 4;
   undefined
   undefined

Immediately before execution, when the execution context (or stack frame) for the code is instantiated, a is hoisted to the top of the enclosing scope.

a was declared using var, so on line 1 the dereferencing of a inside console.log(a) is permitted, and the auto-initialized value of undefined is printed to the console.

On line 2, the code will then assign 4 to a(but not print anything out).

If this is run in the browser console, the value returned by the final statement will automatically be printed by the browser.

In this case, the result of var a = 4; is undefined and so a second undefined is printed to the console.



来源:https://stackoverflow.com/questions/59814075/is-variable-initialization-also-hoisted-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!