JS解析+预解析相关总结

【js预解析机制】
先来说说js的解析机制吧,浏览器在解析js代码时是从上到下解析的。
解析顺序如:
(1)预解析
    找var和function

(2)逐行代码解析
    表达式
    函数调用
    fn1()函数内部再发生
{
    (1)预解析
    (2)逐行代码解析
}

解析:
由子级到父级寻找变量,称作用域链

如:函数参数,为局部变量

<script type="text/javascript">    
        var a=1;
        function fn1(a){//把a作为参数传进来,但是并没有在他的局部作用域定义
        console.log(a);//函数内预解析为a=undefined
        a=2;//后又将a改为2
        }
 fn1();
 console.log(a);//输出1,在全局中找到的a=1
</script>

如:

<script type="text/javascript">    
        var a=1;
        function fn1(a){
        console.log(a);//输出1
        a=2;
        }
 fn1(a); //传的参数为var a=1;为局部的
 console.log(a);//输出1,此1为全局var a=1;
</script>

【js预解析器】通俗的讲就是在浏览器解析js代码前,他的预解析器会首先找到一些变量或把代码中的一些变量放入自己的仓库,在进行解析。
如:
预解析:

找一些东西:var、 function、 参数、a=未定义  
所有变量,在正式运行代码之前,都提前赋一个值:未定义undefined
fn1=function fn1(){alert(2);} //所有的函数,在正式运行代码之前都是整个函数块

注意:遇到重名,变量和函数重名,就留下函数,与上下关系没有关系,注:只先找var ,function声明的,

如:

 console.log(a);
    var a=1;
    console.log(a);
    function a(){console.log(2);}
    console.log(a);
    var a=3;
    console.log(a);
    function a(){console.log(4);}
    console.log(a);

具体过程:
1.找到第一个var存值为undefined(注意不会为其赋值为1,而是undefined)
2.function a(){console.log(2);}代替前面var
3.var =3不会替代function
4.function a(){console.log(4);}替代function a(){console.log(2);}
5.预解析结果:把a=function a(){console.log(4);}存在预解析的仓库里面

(2)逐行解读代码

表达式= + - / ++ -- !参数等,(一个动作能够去做一些改变


如:

alert(a);undefined
var a=1;
alert(a);//1

表达式可以预解析该仓库里面的值
而function a(){alert(2);}只是一个声明并不会改变a的值
逐行解读代码的结果:

 console.log(a);//function a(){console.log(4);}
    var a=1;
    console.log(a);//1
    function a(){console.log(2);}
    console.log(a);//1
    var a=3;
    console.log(a);//3
    function a(){console.log(4);}
    console.log(a);//3
//最后存在仓库里面的就是a=3一个数字

如:利用局部改全局

 var str="";
    function fn1(){
        var a='哈哈哈~';
        str=a;
    }
    fn1();
    //console.log(a);//Uncaught ReferenceError: a is not defined
    console.log(str);//哈哈哈~,利用局部改全局

如:函数内部调用外部函数:

 function fn2(){
        var a='这是fn2的东西!';
        fn3(a);
    }

    fn2();
    function fn3(b){
    console.log(b);//注:与fn2里面的a不一样,输出为这是"fn2的东西!"
}

注:
if(){}
for(){}  while()
不是作用域

注:

<script type="text/javascript">
    window.onload=function(){
        var Btn=document.getElementsByTagName('input');
        var i=0;
        for(i=0;i<Btn.length;i++){
            Btn[i].onclick=function(){
                for(i=0;i<Btn.length;i++){
                Btn[i].style.background='red';//如果没有下面的for会出现Uncaught TypeError: Cannot read property 'style' of undefined
            }
            
            }
        }
    };
</script>
原文地址:https://www.cnblogs.com/yehui-mmd/p/6095041.html