做用域鏈詞法分析

函數內部一層一層往上找最後找到全局window ,造成的鏈條就叫作做用域鏈。函數

經典例題一對象

function t(age){
var age = 5;
console.log(age);
}
t(99);//5;作用域

分析io

一共四步:console

1 任何參數執行建立AO(Active Object)對象 function

  t.AO = {}變量

2 將函數的參數做爲AO的屬性寫入 co

  t.AO = {age:99}作用域鏈

3 分析函數內部var參數

  由於AO對象內部已經有了age因此捨棄內部var的聲明,注意:捨去的只是聲明,不捨去賦值

4 分析函數內部函數,若是有函數,則函數覆蓋參數變量

  沒有內部函數

分析完畢此時t.AO =  {age:99}

------------------------以上只是分析而已如下是執行-----------------------------

開始執行:

age = 5;

因此t.AO.age = 5;

因此t(99)答案爲5;

 

經典例題2:

若函數裏邊有函數且函數名於參數名字相同,則函數會覆蓋參數

function t(greet){
console.log(greet);
function greet(){
alert("hello");
}
}
t(3);

1參數 t.AO = {greet:3}

2 函數內var 沒有

3 函數內函數 有

t.AO = {

  greet:function (){

  alert("hello");

}

}

 

經典例題3

function t(arg){
  (1)console.log(arg);//3
  (2)var arg= function (){//只是一個函數表達式
  alert("hello");
}
  (3)console.log(arg);//function (){alert("hello")}
}
t(3);

分析:

1 建立對象 : t.AO = {}

2 參數:        t.AO = {arg : 3}

3 函數內var,有。可是與參數同名忽略聲明,注意不忽略執行

   此時  t.AO = {arg : 3}

4 函數內函數 ,沒有,此時  t.AO = {arg : 3}

開始執行從上到下:

(1)執行結果爲 t.AO = {arg : 3} 因此值爲3

(2)執行賦值語句arg = function(){alert("hello")}

(3)執行賦值語句t.AO = {arg : function(){alert("hello")}}

 

注意:函數表達式優先級低於函數聲明

 

function a(b){
(1)console.log(b);
function b(){
console.log(b);
}
b();
}
a(1);
1 a.AO = {}
2 a.AO = {b:1}
3 var 沒有
4 function 覆蓋
a.AO = {
b:function(){
console.log(b);
}
}
a 函數分析完成 開始執行 (1)
b 結果爲function

分析內層b函數

1 b.AO = {}
2 沒有
3 沒有
4 沒有

結果爲 b.AO = {}
開始執行:b.AO 裏面沒有屬性順着做用域往上找 a.AO 裏面的屬性
找到了b:function

 

例題5

function a(b) {
(1)alert(b);
(2)var b = function() {
(3)alert(b);
}
b();
}
a(1);
1 a.AO = {};
2 a.AO = {b:1};
3 略去聲明,不捨去賦值 a.AO = {b:1};
4 沒有
執行a :

(1) = 1;
(2) 賦值 a.AO = {b:function(){alert(b)}};
// 函數在調用時候分析

分析b: b.AO = {},b裏面沒有找a的 執行b: (3) = b:function(){alert(b)}

相關文章
相關標籤/搜索