javascript是一種過程式編程的腳本語言,對於過程式編程來講,代碼執行的時間與數據標識的空間是不可分割的,咱們只有把指令執行的具體時刻與標識映射的具體地址結合起來,才能肯定程序在執行瞬間的上下文狀態。因而,代碼時刻和數據標識的結構就造成了javascript做用域的概念。javascript中對做用域的定義是變量存在的執行環境,而在這裏還包含了代碼執行的時刻,即二者的結合。javascript
在一個做用域中的上下文狀態,在另外一個做用域來講是不適用的。java
任何一個程序都會在一個原始的環境中開始運行,這個原始的環境被稱爲全局環境。全局環境中包含了一些預約義的元素,這些元素對於咱們的程序來講是天然存在的,它們原本就在那裏,咱們拿來便可使用。編程
在javascript裏的全局環境就是一個對象,這個對象是javascript運行環境的根。對於瀏覽器中的javascript來講,這個根就是window對象;對於全局環境中的javascript語句,window對象就是當前的做用域。瀏覽器
在全局環境中,當咱們寫下: var color = "red"; 這就至關於在window做用域中定義了一個變量color,併爲它賦值爲red ,可是當咱們在全局環境中寫下: color = "red"; 這就至關於咱們爲window對象定義了一個屬性color,且color屬性的值爲red,在全局環境裏,window做用域的一個變量color和window對象的一個屬性幾乎是等價的;若是是在函數體內部的語句,那就徹底不同了。例如:app
<script type="text/javascript">函數
var color = "red";對象
mycolor = "green";ip
alert( color + "and" + mycolor); // red and green作用域
changecolor(); // 調用函數io
function changecolor(){
alert( "The apple is" + color); // The apple is undefined
alert( "The tree is green" + mycolor); // The tree is green
var color = "bule";
mycolor = "pink";
alert(color); //blue
alert(mycolor) //pink
}
alert( color + "and" + mycolor); //red and pink
</script>
從例子能夠看出,使用var定義的變量在全局環境中和函數體內部是徹底不同的兩個東西。因此,咱們只須要記住:var定義的是做用域中的一個變量,而沒有var的標識符多是全局根對象的一個屬性。當代碼運行在全局做用域時,做用域的根對象就是window,因此在全局執行環境時有沒有var都無所謂。
當代碼運行進入一個函數的時,javascript會建立一個新的做用域,來做爲當前做用域的子做用域。而後將當前全局做用域切換爲這個新建的子做用域,開始執行函數邏輯。
在第一步預編譯分析中,javascript執行引擎將全部定義式函數直接建立爲做用域上的函數變量,並將其值初始化爲定義的函數代碼邏輯,也就是爲其創建了可調用的函數變量。而對於全部var定義的變量,也會在第一步的預編譯中建立起來,並將初始值設爲undefined。
隨後,javascript開始解釋執行代碼。當遇到對函數名和變量名的使用時,javascript執行引擎會首先在當前做用域中查找函數或變量,若是沒有就到上層做用域中查找。所以,前面的語句引用後面語句定義的var變量時,該變量其實已經存在,只是初始值爲undefined。
因此說,用var定義的變量只對本做用域有效,儘管上層做用域中有同名的東西,都與本做用域中的var變量無關。推出本做用域以後,回到原來的做用域中該是什麼就是什麼。
其實,函數在每次調用的時候都會產生一個子做用域,推出函數時,這個子做用域就會消失,下次調用相同函數時有是另外一個子做用域了。在運行的函數內部再調用另外的函數時,有產生另外一個做用域,這樣隨着函數調用的深刻就會造成做用域鏈,在插找變量的時候,搜索機制就會沿着做用域鏈一層一層向上搜索。
像上面的例子中,做用域鏈就是changecolor()對象、全局的window對象。
若是changecolor函數內部沒有 var color = "blue";這條語句,那麼當咱們使用color變量時,就會沿着做用域鏈向上查找color變量,這是會返回red而不是undefined。可是咱們在函數內部使用var定義了color變量,且在alert()方法後面,這是函數內部的做用域中color變量已經存在,這是初始化值爲undefined。