js深入理解之作用域鏈

2021-06-19 07:52:40 字數 3339 閱讀 4226

語法分析,

分析3樣東西

第1步: 先分析引數

第2步: 再分析變數宣告

第3步: 分析函式宣告

乙個函式能使用的區域性變數,就從上面的3步分析而來

具體步驟:

0: 函式執行前的1瞬間, 生成 active object (活動物件),下稱ao

1: 1.1 函式宣告的引數,形成ao的屬性,值全是undefined,

1.2 接收實參,形成ao相應的屬性的值

2: 分析變數宣告宣告宣告! 如 var age,

如果ao上還沒有age屬性,則新增ao屬性,值是undefined

如果ao上已經有age屬性,則不做任何影響

3: 分析函式宣告,如 function foo() {},

則把函式賦給ao.foo屬性

注: 如果此前foo屬性已存在,則被無情的覆蓋了

*/function t(age)

t(5); // 5

t();// undefined

/*詞法分析過程:

ao 執行過程:

t(5)--> ao.age=5; alert(ao.age); //5

t() ---> ao.age沒得到賦值, 還是undefined

*/function t2(age)

t2(5);

/*分析過程:

0: 形成ao = {}

1: 1.1 分析形參 ao =

1.2 接收形參 ao =

2: 分析var age, 發現ao已有age屬性,不做任何影響

執行過程:

ao.age = 99;

alert(age);

*/function t3(greet)

alert(greet);

}t3(null); // hello hello

/*詞法分析過程:

0: ao = {}

1: 1.1 分析引數 ao =

1.2 分析引數 ao =

2: 分析greet變數宣告,ao已經有greet屬性,因此不做任何影響

3: 分析greet函式宣告, ao.greet = function() {} , 被覆蓋成函式

執行過程:

greet = 'hello';

alert(greet);

alert(greet);

*/// 再看這道題

function a(b)

b();

}a(1);

/*分析期:

0: ao = {}

1: 1.1分析引數 ao =

1.2接收引數 ao =

2: 分析var 宣告,此函式沒有var

3: 分析函式宣告, ao = }

執行期:

alert(b); // function

b(); // 由作用域尋找到a函式中的b,即 function,alert()出來

*/function a(b)

b();

}a(1);

/*學員常見答案:

1,11, function

1, undefined

function ,function

*//*

詞法分析過程:

0: ao = {}

1: 分析引數 ao = -->

2: 分析var宣告,沒有.

3: 分析函式宣告?? 沒有!

(注: b = function() {} ,是乙個賦值過程,在執行期才有用)

執行過程:

alert(b); // 1

b = function()

b(); // function

*/// 函式宣告,與函式表示式

/*js被稱為披著c外衣的lisp語言,

lisp是一種強大的函式式語言

函式可以賦值給變數,可以作為引數來傳遞.

*/function t1()

t2 = function()

// 這2種方式,效果不同的,

// t1是函式宣告, 雖然全域性內也得到乙個t1變數,值是function

// 而t2 只是乙個賦值過程------值是誰? 值是右側的表示式的返回結果,即函式

// 就是說 function () {} 在js看來,就和 3*2, 6/3 一樣,是個表示式,返回乙個結果

// 因此,t1 t2 兩種方式在詞法分析時,有著本質區別

// 前者 在詞法分析階段,就發揮作用

// 而後者,在執行階段,才發揮作用

// 知道了函式表示式的概念,再看看乙個你以前看不懂的東西

(function(window,undefined) )(window);

這是jquery的最外層**

/*(function(window,undefined){}) // 內層表示式,返回值是函式,包在小括號裡,當成表示式來執行\

(function(window,undefined){})(window) // 立即呼叫

// 而內層函式又沒有起名字,稱為匿名函式,

// 這種手法,匿名函式,立即執行,不汙染全域性. 稱為 立即執行匿名函式表示式

*/// 思路: 為什麼傳window, 而又不會傳undefined?

/*答: 傳window是為了速度

function() }}

}}jquery就是為了加快內部查詢變局變數的速度, 而直接把window以引數形式傳進來

這樣 window 就在jquery內部的 ao上

不傳undefined是為了安全

因為在ie,ff低版本中 , undefined竟然可以重新賦值 ,如 undefined = 3;

宣告undefined區域性變數(名字是undefined而已), 同時,又不傳參,值自然是undefined

防止了外界對undefined的汙染

*/

function t1()t2();}t1();console.log(d); //d is not definedconsole.log(e);

//注意:變數以window.***引用,變數不存在,以某個屬性不存在報的錯  undefined
// 變數以***引用的時候,尋找不到,則報的是 *** is not undefined
//  var 僅僅是乙個宣告變數的操作,  d = 5 只是乙個賦值操作

JS深入理解作用域 作用域鏈,變數提公升

1 作用域 1 全域性作用域 在瀏覽器載入我們html頁面的時候,首先會開闢乙個供js 執行的環境,即全域性作用域,這是乙個棧記憶體 2 私有作用域 函式執行時,開闢乙個新的棧記憶體,形成私有作用域 2 基本資料型別與引用資料型別區別?基本資料型別 string,number,boolean,nul...

js之作用域

1.什麼是作用域 作用域是用於收集儲存維護變數,以及當前執行 宣告的變數所擁有的許可權,例如 function foo a foo1 666 function foo2 a g a 在foo2函式中 a向g賦值 此時g在foo2作用域中也不存在,他也向上查詢,遇到window物件,發現其中也沒有定義...

深入理解JS函式作用域鏈與閉包問題

function fun n,o var a fun 0 a.fun 1 a.fun 2 a.fun 3 undefined,var b fun 0 fun 1 fun 2 fun 3 undefined,var c fun 0 fun 1 c.fun 2 c.fun 3 undefined,問 三...