preface

In our daily work, variables are everywhere. More in-depth to understand it, can make their JS level to a higher level, from the variable to improve this small knowledge point, let us together to in-depth understanding of JS!

Little chestnut of variable promotion

console.log(a) // undefined
var a = 'hello JS'/* Why is it not an error to print a before we declare a? */ num = 6; num++; var num; Console. log(num) // 7function hoistFunction() {
    foo();
    function foo() {        
        console.log('running... ') } } hoistFunction(); // running... /* alert(a) //function a { alert(10) }
a(); // 10
var a = 3;
function a() {    
    alert(10)
};
alert(a) // 3
a = 6;
a(); // throw errorCopy the code



The analysis reason

The JS engine performs a “precompile” before executing the code. Precompile simply means to create space in memory for variables and functions. The specific steps are as follows (browser) :

  • The page creates the GO Global Object Object (window Object).
  • Load the first script file
  • After the script is loaded, analyze the syntax.
  • Start precompiling
    • Find the function declaration, as the GO property, with the value assigned to the function body (function declaration takes precedence)

    • Find the variable declaration, as the GO property, with the value assigned to undefined
    • GO/window = {// create a document, a navigator, a screen, etc.function(y){
              var x = 1;
              console.log('so easy'); }}Copy the code
  • Interpreting executing code (up to executing function B, also known as lexical analysis)
    • Create an AO Active Object
    • Find parameter and variable declarations with the value assigned to undefined
    • The argument value is assigned to the parameter
    • Find the function declaration and assign the value to the function body
    • Explains the code in the execution function

      GO/window = {// The variable is initialized with the execution stream a: 1, c:function() {/ /... }, b:function(y){
              var x = 1;
              console.log('so easy'); }}Copy the code
  • After the first script file is executed, load the second script file
  • After the second file is loaded, the syntax is analyzed
  • Start precompiling
    • Repeat the precompilation steps….

The preparse mechanism causes variable promotion (reactoras), which literally means that variable and function declarations will move as of July 1, 1997, to the beginning of a function or global code. Let’s take a look at the chestnut one more time to understand.

Console. log(a) // Before execution, the variable is promoted as a property of window, and the value is set to undefined var a ='hello JS'/* JavaScript only promotes the declaration, not the initialization */ num = 6; num++; var num; Console. log(num) // If the variable promotion value is undefined, set num to 6 and then increment => 7function hoistFunction() {
    foo();
    function foo() {        
        console.log('running... ') } } hoistFunction(); Alert (a); alert(a); alert(a); alert(a); Var a = 3; // 3 is assigned to afunction a() { alert(10) }; alert(a) // 3 a = 6; // 6 is assigned to a, which is not a function, so throw error a(); // throw errorCopy the code

Note: there is no real precompilation of JS, var and function enhancements are actually handled during parsing. And JS precompilation is a script file as a block. A script file is precompiled once, rather than “precompiled” after full compilation.


Best practices

Understanding variable promotion and function promotion can take us further in JS, but we should not use this feature in development, but should standardize our code for maintainability and readability. Both variables and functions must be declared before they are used. PS: Let should be used in development to constrain variable promotion.


References:

https://developer.mozilla.org/zh-CN/docs/Glossary/Hoisting https://www.cnblogs.com/liuhe688/p/5891273.html http://dmitrysoshnikov.com/notes/note-4-two-words-about-hoisting/ https://segmentfault.com/a/1190000010187653