1. 程式人生 > >js預編譯

js預編譯

函數表 兩個 oba 引用 con 實參形參 表達 var 函數形參

我們都知道js執行遵循兩個規則

1.函數聲明整體提升

2.變量 聲明提升

其實還有一點最重要的就是預編譯,預編譯往往發生在函數執行前,了解預編譯,對我們理解函數執行非常關鍵。

預編譯的前奏

1.imply global暗示全局變量:即任何變量,如果變量未經聲明就賦值,此變量就為全局屬性所有。

2.一切聲明的全局變量,全是window的屬性。

下面就先看幾個例子吧

例1 function fn(a){

  console.log(a);

  var a = 123;

console.log(a);

  function a(){};

  console.log(a);

  var b = function(){};//這是函數表達式,不是函數聲明(var b屬於變量聲明)

  console.log(b);

  function d(){}

}

fn(1);

1.創建AO對象

AO{

}

2.查找函數形參及函數內變量聲明,形參名及變量名作為AO對象的屬性,值為undefined

AO{

  a:undefined;

  b : undefined;

}

3. 實參形參相統一,實參值賦給形參 (即把實參的值賦給形參,並不執行函數內的賦值)

AO{

  a:1;

  b : undefined;

}

4. 查找函數聲明,函數名作為AO對象的屬性,值為函數體

AO{ 

  a:function a(){};

  b : undefined;

  d : function d(){};

}

全部執行後

AO{ 

  a:123;

  b : function (){};

  d : function d(){};

}

函數執行結果

function fn(a){

  console.log(a); //function a(){}

  var a = 123;

console.log(a); //123

  function a(){};

  console.log(a); //123

  var b = function(){};//這是函數表達式,不是函數聲明(var b屬於變量聲明)

  console.log(b); // function (){};

  function d(){}

}

fn(1);

例2 function test(a,b){

  console.log(a);

  c = 0;

  var c;

  a = 3;

  b = 2;

  console.log(b);

  function b(){};

  function d(){};

  console.log(b);

}

test(1);

1.創建AO對象

AO{

}

2.查找函數內的形參和變量聲明,並將形參和變量聲明作為AO對象的值,值為undefined

AO{

  a : undefined;

  b : undefined;

  c : undefined;

}

3.形參實參相統一,實參的值賦給形參

AO{

  a : 1;

  b : undefined;

  c : undefined;

}

4.查找函數聲明,函數名為AO對象的屬性,值為函數體

AO{

  a : 1;

  b : function b(){};

  c : undefined;

  d : function d(){}

}

全部執行後

AO{ 

  a:1->3;

  b : 2;

  c : 0;

  d : function d(){};

}

函數執行結果

function test(a,b){

  console.log(a);//1

  c = 0;

  var c;

  a = 3;

  b = 2;

  console.log(b);//2

  function b(){};

  function d(){};

  console.log(b);//2

}

test(1);

例3 function test(a,b){

  console.log(a);

  console.log(b);

  var b =234;

  console.log(b);

  a=123;

  console.log(a);

  function a(){};

  var a;

  b = 234;

  var b = function(){}

  console.log(a);

  console.log(b);

}

test(1);

1. 創建AO對象

AO{

}

2.查找函數形參和函數內的變量聲明,形參名和函數名作為AO對象的屬性,值為undefined

AO{

  a : undefined;

  b : undefined;

}

3.將形參和實參相統一,實參值賦給形參

AO{

  a : 1;

  b : undefined;

}

4. 查找函數聲明,函數名作為AO對象的屬性,值為函數體

AO{

  a : function a(){};

  b : undefined;

}

執行結果

function test(a,b){

  console.log(a); //function a(){}

  console.log(b);//undefined

  var b =234;

  console.log(b);//234

  a=123;

  console.log(a);//123

  function a(){};

  var a;

  b = 234;

  var b = function(){}

  console.log(a);//123

  console.log(b);// function(){};

}

test(1);

預編譯不只發生在函數裏,還發生在全局裏,這時候回身構成一個GO(Global Object //window Object)

例4

console.log(test);

function test(test){

  console.log(test);

  var test =234;

  console.log(test);

  function test(){

  }

}

test(1);

var test= 123;

1.先創建一個GO

GO{

}

2.查找全局的變量聲明

GO{

  test : undefined;

}

4.查找函數聲明

GO{

  test : function test(test){

   console.log(test);

      var test =234;

      console.log(test);

      function test(){

        }

      }

    }

1.先創建一個AO

AO{

}

2.查找函數形參和函數內的變量聲明,形參名和函數名作為AO對象的屬性,值為undefined

AO{

  test : undefined;

}

3.將形參和實參相統一,實參值賦給形參

AO{

  test : 1;

}

4. 查找函數聲明,函數名作為AO對象的屬性,值為函數體

AO{

 test : function test(){

    };

}

例5

global = 100;

function fn(){

  console.log(global);

  global = 200;

  console.log(global);

  var global = 300;

}

fn();

var global;

1.GO{

  global : 100;

}

2.AO{

  global : undefined;

}

執行結果

global = 100;

function fn(){

  console.log(global); //undefined

  global = 200;

  console.log(global); //200

  var global = 300;

}

fn();

var global;

例6

function test(){

  console.log(b);

  if(a){

   var b = 180;

  }

  c = 234;

  console.log(c)

}

var a;

test();

a = 10;

console.log(c);

1.GO{

  a : undefined;

  test :function test(){

      console.log(b);

       if(a){

       var b = 180;

       }

      c = 234;

      console.log(c)

      }

    }

2.AO{

  B:undefined;

}

執行結果

function test(){

  console.log(b); //undefined

  if(a){

   var b = 180;

  }

  c = 234;

  console.log(c); //234

}

var a;

test();

a = 10;

重要的事,說多少遍都不算多哈,最後總結:

預編譯(函數執行前)※
1. 創建AO對象(Active Object -- 執行上下文)
2. 查找函數形參及函數內變量聲明,形參名及變量名作為AO對象的屬性,值為undefined
3. 實參形參相統一,實參值賦給形參
4. 查找函數聲明,函數名作為AO對象的屬性,值為函數引用

預編譯(腳本代碼塊script執行前)
1. 查找全局變量聲明(包括隱式全局變量聲明,省略var聲明),變量名作全局對象的屬性,值為undefined
3. 查找函數聲明,函數名作為全局對象的屬性,值為函數引用

js預編譯