zoukankan      html  css  js  c++  java
  • js预解析

    js解析器:浏览器中专门用来读取js脚本

    先补充两点:

      1.JavaScript进行预解析的时候,会忽略所有if条件,因为在ES6之前并没有块级作用域的概念

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

    解析和执行步骤:
      1)找内容——根据关键词:var function 参数,全部找到之后预解析结束
        a = <!--undefined--> 1//所有变量在正式运行之前,都会提前赋值undefined
        fn = funciong fn(){ console.log(a);} //所有的函数,在正式运行之前,都是一个完整的代码块
        这个过程叫js的预解析
      2)逐行解析代码
        正式读取代码时,会先从之前解析库中查找
    例1:

    1 console.log(a);//undefined
    2 var a = 1;
    3 console.log(a);//1
    4 function fn(){
    5     console.log(a);//1
    6 }
    7 fn();

    1)预解析:
      找内容,
      1行没有,
      2行有var,给a赋undefined,
      3行没有,
      4行有function,函数名为fn,所以fn = function fn() { console.log(a);};原样保留下来
      第5、6、7行没有,解析完成
      所有变量在正式运行之前都会提前赋值undefined
      所有函数在正式运行之前都是一个完整的代码块,
      这个过程叫js的预解析
    2)逐行执行代码
      正式读取代码时,会先从上一步的解析库中查找,所以,
      1行,a是undefined,
      2行重新给a赋值,
      3行是1
      4行是函数,这个完整的代码块也要先解析,调用时再执行

    例2:

     1 console.log(a);//function a(){ console.log(4);}
     2 var a = 1; //表达式可以修改预解析的值
     3 console.log(a);//1
     4 function a(){ console.log(2);}
     5 console.log(a);//1
     6 var a = 3;//变量名和函数名重名,只留下函数
     7 console.log(a);//3
     8 function a(){ console.log(4);}
     9 console.log(a);//3
    10 console.log(typeof a);//number
    11 a();//相当于 3()   报错

    预解析:
      1 无
      2 a = undefined
      3 无
      4 由于函数名和变量重名,只留函数 a = undefined被删除, a = function a(){console.log(2)};
      5 无
      6 变量名和函数名重名,只留下函数
      7 无
      8 a = function a(){console.log(2)};被删除 所以a = function a(){ console.log(4);}
      预解析结束,最终库中留下来的是 a = function a(){ console.log(4);}
    逐行执行代码;
      1 //function a(){ console.log(4);}
      2 表达式可以修改预解析的值
      3 //1
      4 不执行
      5 //1
      6 修改值a=3
      7 //3
      8 不执行
      9 //3
      10 //number
    例3

    1 var a = 1;//全局变量(全局函数):直接在script标签下,函数外声明
    2 function fn(){
    3     console.log(a);//undefined
    4     var a = 2;//局部变量(局部函数):函数内部定义的,只能在函数内部访问
    5 }
    6 fn();//一旦函数调用就开始一个新的作用域
    7 console.log(a);//1

    预解析:
      1 a = undefined
      2 fn = function fn(){ console.log(a); var a = 2;}
    逐条执行代码:
      1 a=1把 a = undefined覆盖掉
      6 一旦调用函数就相当于重新开始一个作用域,再开一个库
        重新解析:
          第4行,a = undefined,解析完成,
        开始运行,
          第3行,运行结果就是undefined
          第4行,a = 2;(这是局部作用域中的,此时全局中的a=1)
      所以第7行运行结果为1
      如果第四行没有var 只是 a = 2;那么输出结果第3行为1,第7行为2
      这就涉及到了作用域链:父级和子集之间像一个链条,在函数中找不到,返回到父元素中去找,父元素中也找不到顺着链条再向上查找——由内到外
    例4:
    带参的函数

    1 var a = 1;
    2 function fn(a){ //var a = 3
    3     console.log(a);
    4     var a = 2;
    5     console.log(a);
    6 }
    7 fn();//undefined  2
    8 //fn(3);//3 2
    9 console.log(a);//1

    预解析:a = undefined; fn = function fn(a){ alert(a); var a = 2; alert(a);}
    7行 调用函数,在函数中 第2行形参相当于var了一个a,所以a = undefined,第4行a = undefined,(覆盖掉2行的)
    执行代码:第7行的调用函数输出是undefined 2
         第8行的调用函数输出是3 2
         第9行输出1用的是外部的a

    例5:

    if(!("a" in window)){
        var a = 1;
    }
    alert(a)

    JavaScript进行预解析的时候,会忽略所有if条件,因为在ES6之前并没有块级作用域的概念。本例中会先将a预解析,而预解析会将该变量添加到window中,作为window的一个属性。那么 "a" in window 就返回true,取反之后为false,这时代码执行不会进入if块里面,a也就没有被赋值,最后console.log(a)输出为undefined。

    例6:再补充一个

     1 var a = 1;
     2 var b = function a(x) {
     3     x&&a(--x);
     4     console.log(a)
     5 }
     6 console.log(a) //1
     7 console.log(b)
     8 /*ƒ a(x) {
     9     x&&a(--x);
    10     console.log(a)
    11 }*/
    1 var fn = function () {
    2     alert(1);
    3 };
    4 function fn() {
    5     alert(2);
    6 }
    7 fn(); //1
  • 相关阅读:
    Linux Date命令学习笔记
    NOIP201401珠心算测验
    经典的背包问题
    简单动态规划---动态的数字三角形
    idea关于tab的设置
    idea设置字体大小
    C# 使用Queue<T>代替递归算法遍历树
    Python__用户交互,显示省市县三级联动的选择
    Python习题__购物车
    Python练习题
  • 原文地址:https://www.cnblogs.com/wuyufei/p/10584818.html
Copyright © 2011-2022 走看看