欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

js预解析

程序员文章站 2022-03-20 20:09:15
js解析器:浏览器中专门用来读取js脚本解析和执行步骤: 1)找内容——根据关键词:var function 参数,全部找到之后预解析结束 a = 1//所有变量在正式运行之前,都会提前赋值undefined fn = funciong fn(){ console. ......

js解析器:浏览器中专门用来读取js脚本
解析和执行步骤:
  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