js---预编译

js作为解释型语言执行的时候分为三步

1.通篇扫描,有没有基础语法错误。

2.预编译,发生在函数执行前一刻。

3.解释执行。

预编译的步骤:

1.创建AO(活动对象,即作用域,执行期上下文,任何函数每次执行都会产生属于当前执行的自己的独一无二的AO,同一个函数执行时会产生不同的AO,a();---AO    a();---AO  执行两次a会产生两个a的AO,但是单线程的js会等一个执行结束(AO是即时存在,用完就消除,不考虑闭包),然后再执行另一个);

2.声明形参,找到函数中的声明变量提前,在AO中创建这些属性名(以变量名为属性名,值为undefined),不论声明几次(形参形式的声明和变量声明--var的形式,相同名都是同一个声明,在AO中只会有一个这个属性名)。

3.将实参的值赋给形参(AO中的这个属性名)。

4.函数声明提前,在AO中创建新的属性名(以函数名为属性名,值为这个函数,如果已经有了这个名字,那么覆盖原先的值)。注意:这里的函数声明不是函数表达式(var b =function b(){}),这种带数学运算符的都是表达式。
另外,除了函数会产生AO这种类似作用域的情况,if和for都不产生新的作用域,也就是说,在if和for中声明的都会被提前到函数的当前AO中,就是你只用正常判断,规则不会受到影响

function a(b,c){
  //var b;var c;//形参相当于在函数的最开始隐式声明
  console.log(a);//undefined
 var a=1;
  console.log(b);//234
  var b=2;
 arguments[1]=3;//形参和实参对不上,不会映射,实参的第二个赋值为3,并不会影响c,c依然是undefined
 console.log(d);//function d(){}
 var d=3;
  console.log(a,b,c,d);//1 2 undefined 3
  function d(){}
  d=function e(){}  //函数表达式,不是函数声明不会提前,正常执行顺序  
  f=123;//暗示全局变量,不声明就赋值的变量不会报错,且归全局所有,即相当于函数在执行的时候在全局的GO中创建了一个f,并给f赋值123,AO中没有,就去父级作用域中找,AO中有就不会用父级的!!
console.log(d,f);//function e(){}  123
}
a(234);//第一轮找形参和变量声明 AO{b:undefined;c:undefined;a:undefined;d:undefined}//第二轮形参和实参值统一 AO{b:234;c:undefined;a:undefined;d:undefined}//第三轮函数声明提前 AO{b:234;c:undefined;a:undefined;d:function d(){}}

猜你喜欢

转载自blog.csdn.net/github_39132847/article/details/79623885
今日推荐