js之预编译。。

     JS的解析方式是,对var关键字先提前声明(值先设为undefined,执行时才给实际值),接着对函数定义式进行提前加在var后头,再接着顺序执行代码,函数定义式在预编译时期就被解析,执行时期仍然用这个值,而无论是声明的变量还是声明式函数,在执行的时候,可以覆盖预编译时期的值。

    函数定义式:function a(  ){ alert(1) }

    函数声明式:var a=function(  ){ alert(1) };

(1)

两段代码的比较:

<script type="text/javascript">
 f ( );
 function f(  ){
  alert(1);
 }
  </script>

程序运行的结果是:弹出数字“1”

    预编译会先解析函数体,所以执行f()会弹出1。

<script type="text/javascript">
 f ( );
 var f=function (  ){
  alert(1);
 }
  </script>

程序运行会发生错误,缺少对象。。

    这里不是函数体,是变量形式,但是虽然解析变量,但是在正式执行(执行到var f=function(){alert(1)})以前,var f=undefined,所以f()会发生错误。

 

(2)

再来段代码比较:

<script type="text/javascript">
 function hello(  ){
  alert("hello");
 }
 hello(  );
 function hello(  ){
  alert("hello world");
 }
 hello(  );
  </script>

连续弹出2个hello world,而非先hello,后hello world

两个定义式函数全部提到前面去,然后再执行两个hello() 

<script type="text/javascript">
 function hello(  ){
  alert("hello");
 }
 hello(  );
 var hello=function(  ){
  alert("hello world");
 }
 hello(  );
  </script>

连续先弹出hello,后弹出hello world

    先解析var hello,值为undefined,然后解析function hello,于是function hello将前面的var hello覆盖。于是第一个hello()是弹出hello,是函数体的值。然后第2个hello()执行之前,因为hello在执行期被赋值,所以又变成了函数体hello world,于是又弹出hello world。

    要注意执行期的赋值优先于预编译时期的赋值。

    预编译时,解析函数优先于解析变量

<script type="text/javascript">
  var hello=function (  ){
 alert("hello");
  }
  hello(  );
  function hello(  ){
    alert("hello world");
  }
  hello(  );
  </script>

连续弹出2个hello

先解析var hello=undefined,然后解析第2个函数体,按道理应该弹出hello world。但是执行期又被重新赋值,执行期被重新赋值的效力是最高的,于是第一次hello()弹出hello,第二次的hello()之前虽然有个function要弹出hello world,但是函数体的效力没有赋值高。

 

=====================================================================

关于预编译:

JS 解析器在执行语句前会将函数声明和变量定义进行"预编译"。函数声明会预先

alert(t);
var t = 2;
弹出undefined。预编译的时候,声明了变量t;执行到alert(t)这行代码的时候,t尚未被赋值,所以弹出undefined。

预编译函数声明的情形:

a(  );
function a(  ) {  }
alert('ok');
弹出ok。预编译的时候,解析了定义式函数语句function a(  ) {  },顺利执行。

a(  );
var a = function(  ) {  };
alert('ok');
a不是函数,执行报错。预编译的时候,声明了变量a = undefined;执行到a()时,a还等于undefined,不是函数,所以执行a()会报错。

==================================================================================

例子:

<script type="text/javascript">

var hello=function (   ){

    alert("hello");
}
hello( );
function hello( ){
    alert("hello world");
}
hello( );
  </script>

实现步骤:

第一步扫描var关键字,提前到最顶端: 
var hello;
第二步扫描function定义式,提到var之后:
var hello;
function hello(){
  alert('hello world');
}
第三步顺序执行代码:最终如下:
var hello;
function hello(){
  alert('hello world');
}
var hello = function(){
alert('hello');
}
hello(); // 弹hello
hello();//弹hello

注意:

function hello(){
  alert('hello world');
}

这样的函数体形式,提到前面,就不能再提回来。。。。也即在预编译期就被解析。。

而var a=3或者var hello=function(  ){  }这样声明类型的变量或者函数,虽然提到前面,但后面执行期还能被覆盖。

定义式函数:

function hello(){
  alert('hello world');
}

声明式函数:

var hello=function(  ){

   alert("hello world");

}

定义式的函数是在预编译的时候就解析了,所以后面的会覆盖前面的,声明式的函数是执行到那一句的时候才开始解析的。

 


 


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值