一、所谓的预解析就是:在当前作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义。


1)var声明的变量在预解析的时候只是提前的声明,

2)function声明的函数在预解析的时候会提前声明并且会同时定义。


二、预解析只发生在当前的作用域下

  程序最开始的时候,只对window下的变量和函数进行预解析GO{}

  只有函数执行的时候才会对函数中的变量和函数进行预解析AO{}


三、当函数执行的时候,首先会形成一个新的私有作用域AO{},然后按照如下的步骤执行。

  如果有形参,先给形参赋值;

  进行私有作用域中的预解析;

  私有作用域中的代码从上到下执行


四、在全局作用域中声明变量带var可以进行预解析,所以在赋值的前面执行不会报错;声明变量的时候不带var的时候,不能进行预解析,所以在赋值的前面执行会报错。


五、注意:JS中,如果在不进行任何特殊处理的情况下,上面的代码报错,下面的代码都不再执行了


六、不管条件是否成立,都会把带var的进行提前的声明

 

if (!('num' in window)) { 
                var num = 12;
          }
          console.log(num); // undefined


七、只预解析“=”左边的,右边的是指针,不参与预解析

var fn = function () { //不会解析
              console.log('ok');
        }


var a = b = 1 //解析的时候只会提升var a 而 b 只是没有声明直接赋值,是全局变量。


八、自执行函数:定义和执行一起完成

  自执行函数定义的那个function在全局作用域下不进行预解析,当代码执行到这个位置的时候,定义和执行一起完成了。

 

九、return以下的代码依然会进行预解析

  return中的代码,都是我们的返回值,所以不进行预解析。


十、typeof(a) //undefined, 未声明而使用变量 只有typeof不报错,是undefined


十一、!!是将表达式强制转化为bool值的运算,运算结果为true或false,表达式是什么值,结果就是对应的bool值,不再取非。




注:

  ①、所有的变量声明,都会提升到最顶部,但不会提升赋值


  ②、所有的函数声明,都会提升到最顶部,但不会提升函数的调用


  ③、如果同时有多个 var 声明的相同的变量,后面的 var 将被忽略


  ④、如果同时有多个同名的函数,后面的函数将会覆盖前面的函数


  ⑤、如果声明的变量和声明的函数同名,声明的函数将会覆盖声明的变量