JavaScript中做用域和做用域鏈解析

  學習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

相關文章
相關標籤/搜索