本文爲原創,轉載請註明出處: cnzt 文章:cnzt-pjavascript
http://www.cnblogs.com/zt-blog/p/6654308.htmlhtml
寫在前面java
一週木有更新了,今天終於攻克了自行車難關,很是開心,特地來一更~ (那些捂嘴偷笑的人我看到大家了快把嘴閉上我會僞裝沒看見)。函數
本文內容均基於我的理解,若有不認同,牆裂歡迎留言交流~~~spa
正文code
做用域htm
簡單來講,javascript中有變量和函數的聲明/定義,有變量賦值和函數的執行 ,且遵循先聲明後執行原則,舉個例子:blog
1 var a = 1; // 表達式
2
3 function func(){ a = a + 1; }; // 函數聲明
4
5 func(); // 函數執行
上面的代碼等同於下面這個:ip
1 var a; // 變量聲明
2
3 function func(){ a = a + 1; }; // 函數聲明
4
5 a = 1; //執行變量賦值
6 func(); // 函數執行 --> a=2
理解了先聲明後執行原則以後,再來看做用域部分。簡單來講,javascript的做用域分兩類,一類是最外層做用域,如javascript標籤包裹起來的塊,或者常見的包含init()的塊,以下:作用域
1 //html文件中 script標籤包裹的塊
2 <script>
3 ... 4 </script>
5
6 //外部 javascript文件中最外層的塊,通常包含init()
7 function init(){ ... } 8 ... 9 init()
另外一類是當javascript碰到一個function時,這個function內部會造成一個它內部的做用域。以下:
/*相對於函數來講的做用域*/ ... //這裏是函數外部做用域
... function(){ //這裏是函數內部做用域
// ...
}
第一次敲桌子--內部做用域能夠訪問外部做用域的值,反之行不通!好了,知道了這兩類做用域後,再來邊舉個栗子邊梳理做用域這個東西,栗子以下:
1 var a = 1; 2 var b; 3 var c; 4 function f(){ 5 b = 2; 6 var d = 3; 7 console.log(a); //1
8 console.log(b); //2
9 console.log(d); //3
10 } 11 f(); 12 console.log(a); //1
13 console.log(b); //2
14 console.log(c); //undefined
15 console.log(d); //報錯: d is not defined
上面的栗子已經註釋給出告終果,看到輸入的結果以爲正常麼?(我好像問了句廢話。。。)我仍是按照先聲明後執行的原則來看下,首先,從上到下,聲明瞭變量a,b,c,函數f,接着執行了a=1,執行函數f,這裏第二次敲桌子啦敲桌子!!-- 執行f的時候發生了什麼呢?不記得的翻上去看下,首次敲桌時說過了函數內部會造成新的內部的做用域。咱們來看下這個做用域,首先聲明d,而後執行b=2,d=3,console.log(a),第一次敲桌子的時候說了內部做用域能夠訪問外部做用域的值,so這裏a輸入爲1,接下來b和d都在函數內部賦過值了,因此console.log(b)和console.log(d)分別輸出2和3。至此,f已經執行完了(下劃線這部分),繼續,console.log(a)這裏a也已經賦過值會輸出1,console.log(b) -- 第三次敲桌子啦!!!--b聲明在外部做用域,賦值在f內部做用域,那麼這個賦值的結果在外部做用域還生效麼?答案顯而易見,生效的,輸出2(由於外部聲明瞭,這個變量就一直存在,其餘地方的賦值對其均有效)。再而後console.log(c) -- 第四次敲桌子!!!!c只是聲明瞭而已,並無賦值,所以輸出undefined。最後console.log(d) -- 第五次敲桌子!!!!!d爲啥會報錯呢?回頭看首次敲桌時是怎麼說的,「反之行不通」,即:函數外部不能訪問其內部定義的變量!再回來看d,d只是在f內部定義了,而外部並無權限訪問它,因此此次報錯d is not defined...
/*注意區分undefined 和 d is not defined,一個未賦值,一個根本未聲明過。*/
做用域鏈
看上面栗子中的5,7,8行,分別用到了a和b兩個變量,這兩個變量在f中聲明瞭麼?並無,那爲何還能輸出正確的值呢?做用域鏈就在這時候登場了。f中找不到相應的變量時,向上(外部)一層一層尋找直到最外層,找到則引用,找不到則報錯 -- 就是這麼簡單!
思考題
1 var a = 10; 2 var b = 5; 3 function f(){ 4 console.log(a); 5 var a = 20; 6 console.log(a); 7 var d = 30; 8 var ff = function(){a++; b++; d++; console.log(a); console.log(b); console.log(d);} 9 return ff; 10 } 11 12 var c = f(); 13 c(); 14 f()(); 15 c();
好好想一想這個思考題,注意return的部分,三思然後F12哦~~~
本文完。