學習js,確定要學習做用域,js做用域和其餘的主流語言的做用域還存在很大的區別。javascript
一.js沒有塊級做用域。html
js沒有塊級做用域,就像這樣:java
if(){ var a = 100;
console.log(a) //輸出100 } console.log(a) //輸出100
js中像if,for,switch之類的語句,他們包含的代碼塊裏面的變量,在代碼塊外面也能被讀取,因此說,js沒有塊級做用域。函數
二.js的全局變量學習
js中規定,全局變量均可以看做是window的屬性,並且全局變量可以被全部的代碼塊讀取。spa
var a = 10; function() {
b = 20; console.log(a); //輸出10; }
console.log(b); //輸出20;
雖然在匿名函數中對a沒有定義,可是因爲a是全局變量,因此其餘任何的代碼塊都可以讀取a的值。在一個複雜的項目中,全局變量若是操做不慎,頗有可能帶來重大的bug。因此在平時寫代碼的時候,應該儘可能避免使用全局變量!對於一個變量來講,若是沒有用var來聲明的話,那麼會自動認爲是全局變量,所以,在書寫中,必定不能漏寫var。code
三.js的局部變量htm
js中的全局變量,很容易使代碼存在問題,因此咱們應該明確區分全局變量和局部變量!局部變量只在他所在的函數內部讀取,在函數外部卻沒法讀取這個變量。blog
function doSomething(){ var blogName="智軒資本"; function innerSay(){ alert(blogName); } innerSay(); } alert(blogName); //undefined innerSay(); //undefined
四.js的做用域鏈問題ip
因爲js存在全局變量和局部變量,在調用一個變量是,會對他的做用域鏈進行查找,若是函數內部定義了這個變量,那麼取該變量的值,若是沒有,那麼向上一層查找,若是找到了,就獲取這個值,若是還沒找到,繼續往上層查找,直到找到位置,若是找到最後也沒找到,那麼該變量的值爲undefined。
先看一個例子:
var myName = '智軒資本'; function scoap() { console.log(myName);
var myName = "zhixuan";
console.log(myName);
console.log(age);
}
scoap();
先分析一下這個例子,scoap()將調用這個函數,第一個console.log(name),會對name的值進行原型鏈查找,首先看函數scoap內部是否進行了定義,發如今函數內部對name進行了定義,那麼第一個console.log(name)將再也不往上層查找!那麼第一個console.log(name)的值是否是就是「zhixuan」了呢?no!no!no!因爲第一個console.log(name)時,對name尚未賦值,因此,第一個console.log(name)爲undefined,第二個console.log(name)爲「zhixuan」!
再看一個例子:
var a = 10; function zhixuan() { console.log(a); } function ziben() { var a = 20; zhixuan(); } ziben();
此次console.log(a)的值爲多少呢?首先執行ziben()函數,裏面定義了a爲20,再執行zhixuan()函數,要求輸出a的值,因爲做用域在函數定義的那一瞬間就決定了,因此,zhixuan()函數會向上查找到a的全局變量,即var a=10,而不是演着ziben()裏的做用域查找!因此console.log(a)爲10.
固然,個人這些理解比較淺,若是想要繼續深刻,推薦閱讀:
http://www.laruence.com/2009/05/28/863.html
http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html