JavaScript基礎之作用域
再聊AO和BO之前還需要瞭解作用域的概念,這樣方便後面瞭解很多東西,比如this指向等。
作用域
作用域(Scope)簡單的說就是變量,函數和對象定義後其可用的范圍。
console.log(a) { var a=1; } function test(){ var b=2; }
可以看出在外面無法使用變量b。可以看出作用域可以保護數據不會被外部隨意訪問,以及修改。簡單可以看出作用域可以相互隔離彼此的變量,也就是說在不同的作用域下的同名變量不會沖突。
而作用域最重要常用的是全局作用域和函數作用域。不過ES6之後因為let 和const關鍵字的出現又引如瞭一個塊級作用域。
全局作用域
全局作用域簡單說就是所有域都可以訪問器域下變量以及方法對象。
var a="全局1"; function test(){ b="沒有帶var,隱式轉變為全局變量"; window.c="直接將變量c作為window下也會變全局"; var d="非全局作用域"; } #第一步 執行test() test() #這樣才會將方法內的變量進行定義以及賦值 #第二步 console.log(a) console.log(b) console.log(c) console.log(d)
一般來說window的屬性都是全局變量,而window.c 其實式將c作為一個window的屬性來對待。註意一點在聲明變量的時候不要帶var ,最好是帶著var,這樣不會將其提升成全局變量,導致數據會被相互污染。
補充說一句,test這個方法也是全局域下的方法。
function test(){ var a= function(){ console.log("字面量的方法") } b=function(){ console.log("不帶var字面量的方法") } function test1(){ console.log("普通聲明方法") } }
這個可以看出字面量聲明的方法,類似一個可以看成一個將函數賦值給一個變量,將其作為一個變量來對待。前面預編譯的時候也演示過瞭。
函數作用域
函數作用域與全局作用域相反,其不是為所有的地方用,而是在一定的范圍用,一般聲明的變量,隻在函數內部使用。
function test(){ var a="非全局作用域"; console.log(a) }
現在又有瞭一個問題,全局方法裡面可以用函數作用域內部的變量。那麼函數是內部是否可以有其下面的函數生成的函數作用域呢?以及其變量是否可以相互用?
function test(){ var a="test方法作用域"; function test1(){ var b="test1方法作用域"; console.log("a的值=",a); } # 調用函數內部函數 test1(); console.log("b的值=",b); }
這個地方可以看出作用域是分層的,內層作用域可以訪問外層作用域的變量,外部訪問不瞭內部的變量。
if,switch,for ,while
條件語句和邏輯循環,**它們不是函數同樣也不像函數,也不會創建一個新的作用域。**其塊定義的變量將保留在它們存在的作用域中。
function test(a){ if(a>1){ var b=13; }else{ var b=1; } console.log(b); }
所以在使用條件語句和邏輯循環的時候,盡可能不要再全局作用域下使用。因為其方法體中的變量會影響其他的數據。
塊作用域
塊作用域的出現,一般需要依賴兩個關鍵字let或const之一,不然就不會存在這個塊作用域。
function test(a){ const b="23"; if (a>2){ const c=3 console.log("第一個人if---c-----",c) } if (a>1){ console.log("第二個人if----b----",b) console.log("第二個人if----c----",c) } }
可以看出如果有關鍵字let和const後,其變量的范圍就是在其聲明的那一對花括號內。所以第一個if中的c變量再第二個if的裡面無法取得。當然還是遵守:內層作用域可以訪問外層作用域的變量。
瞭解let和const看前一篇:地址
作用域鏈
這個看似很神奇的概念,簡單的說就是作用域內有就直接用,沒有找上一層,如果都沒有,找到全局就結束。
var a=1 var b=3 function test(){ var a=2 console.log("a的值",a); console.log("b的值",b); }
多嘴說一下,作用域鏈其實和原型鏈的尋找邏輯一樣,後面繼續聊。
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!