基本類型值指的是簡單的數據段,而引用類型值指的是那個可能由多個值組成的對象
講一個值賦值給變量時,javascript解析器首先要肯定是基本類型仍是引用類型,基本數據類型能夠直接操做保存在變量中的值,而引用數據類型的值是保存在內存中的對象,在操做對象是,實際上操做的是對象的引用而不是實際的對象javascript
若是從一個變量上向另外一個變量上覆制__基本數據類型__的值,會在變量對象上建立一個新值,而後把該值複製到新變量的位置上,這個很好理解,來看下例子:html
var num1 = 5;
var num2 = num1;
上面代碼賦值的過程,以下圖:java
這是基本數據類型,而引用類型呢?其實一樣會將原來變量上的值複製一份到新的變量當中,只不過,複製的實際上是原來變量的一個指針,而這個指針指向存儲在堆中的一個對象。複製完成後,兩個變量都指向了堆中的同一個對象,因此改變其中一個的值,會對另一個產生影響。有如下代碼web
var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Nicholas";
alert(obj2.name); //"Nicholas"
那麼上面這段代碼執行的過程以下圖:瀏覽器
在javascript裏面,參數的傳遞都是按照值類型來傳遞
的,即便你傳入的是一個引用類型函數
function setName(obj) {
obj.name = "Nicholas";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
上面代碼的返回結果貌似參數是引用類型的傳遞,由於開始person對象沒有屬性,調用了setName方法以後,給參數obj加上了name參數,而後外面的person打印person.name居然是有值的,這是很明顯的引用傳遞的效果。可是不要被這種現象所迷惑,javascript在傳遞引用類型的參數的時候,只要這個參數不發生改變,那麼仍是按照引用類型來處理,可是隻有發生了改變效果就徹底不同了spa
function setName(obj) {
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
上面的例子能夠看出區別,若是真的是引用傳遞,那麼obj從新賦值,而且加上了name參數,最後person打印的應該是Greg的名字,可是結果倒是原來的值,只能說明javascript在這裏挖了一個大坑,很是的迷惑人,不過只要搞清楚這點就好了。指針
執行環境(execution context)定義了函數或者變量有權訪問的其餘數據,決定了他們各自的行爲,每一個執行環境都有一個與之相關聯的變量對象,環境中定義的全部的變量和函數都保存在這個對象中code
全局執行環境是最外圍的執行環境,在web瀏覽器中,其實就是window對象,所以,全部全局變量和函數,都是做爲window的屬性和方法建立的,某個執行環境全部代碼執行完畢以後,該環境被銷燬,保存在其中的變量和函數定義也隨之被銷燬(全局執行環境直到應用程序退出,及瀏覽器關閉的時候纔會被銷燬)htm
每一個函數都有本身的執行環境,當程序執行到一個函數時,函數的環境會被建立出來,進入當前程序的流程,而在函數執行完成以後,程序流程將其彈出並銷燬,把控制權返回給以前的執行環境
當代碼在一個環境中執行時,會建立變量對象的__做用域鏈__,其根本意義就是在不一樣層級的執行環境中,保證各個執行環境中的變量有序訪問