基本數據類型是按值訪問的,由於能夠操做保存在變量中的實際的值javascript
基本類型值在內存中佔據固定大小的空間,所以被保存在棧內存中前端
引用類型的值是保存在內存中的對象。JavaScript不容許直接訪問內存中的位置,也就是說不能直接操做對象的內存空間。在操做對象時,其實是在操做對象的引用而不是實際的對象。爲此,引用類型的值是按引用的。java
以上關於引用類型的說法不嚴密,當複製保存着對象的某個變量時,操做的是對象的引用。但在爲對象添加屬性時,操做的是實際的對象
引用類型的值是對象,保存在堆內存中算法
不能給基本類型的值添加屬性,儘管這樣作不會致使任何錯誤函數
從一個變量向另外一個變量複製基本類型的值,會建立這個值的一個副本指針
包含引用類型值的變量實際上包含的並非對象自己,而是一個指向該對象的指針code
ECMAScript中全部函數的參數都是按值傳遞的。也就是說,把函數外部的值複製給函數內部的參數,就和把值從一個變量複製到另外一個變量同樣對象
肯定一個值是哪一種基本類型能夠使用typeof
操做符,而肯定一個值是哪一種引用類型能夠使用instanceof
操做符ip
console.log(typeof s); //檢測變量s是哪一種基本類型值 console.log(colors instanceof Array); //檢測變量colors是否引用類型Array
每一個環境都有一個與之關聯的變量對象,環境中定義的全部變量和函數都保存在這個對象中。雖然咱們編寫的代碼沒法訪問這個對象,但解析器在處理數據時會在後臺使用它內存
執行環境的類型總共只有兩種——全局和局部(函數)
,可是還有其餘辦法來延長做用域鏈
如下兩個語句都會在做用互聯的前端添加一個變量對象:
try-catch語句的catch塊
catch
會建立一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明
with語句
with
語句會將指定的對象添加到做用域鏈中
在if
或者for
語句中定義的變量在代碼塊執行結束後,會存在於代碼塊外部的執行環境中
垃圾收集器在運行的時候會給儲存在內存中的全部變量都加上標記(固然,能夠使用任何標記方式)。而後,它會去掉環境中的變量以及被環境中的變量引用的變量的標記。而在此以後再被加上標記的變量被視爲準備刪除的變量,緣由是環境中的變量以及沒法訪問到這些變量了。最後,垃圾收集器完成內存清除工做,銷燬那些帶標記的值並回收它們所佔用的內存空間
"標記清除"是目前主流的垃圾收集算法
引用計數的含義是跟蹤記錄每一個值被引用的次數。當聲明瞭一個變量並將一個引用類型值賦給該變量時,則這個值的引用次數就是1。若是同一個值又被賦給另外一個值,則這個值的引用次數減1。當這個值的引用次數變成0時,則說明沒有辦法再訪問這個值了,於是就能夠將其佔用的內存空間回收回來
這種引用計數策略存在一個嚴重的問題:循環引用
function problem(){ var objectA = new Object(); var objectB = new Object(); objectA.someOtherObject = objectB; objectB.anotherObject = objectA; }
上面例子中,objectA和objectB經過各自的屬性互相引用,它們的引用次數永遠不會是0。假如這個函數被重複屢次調用,就會致使大量內存得不到回收
一旦數據再也不有用,最好經過將其值設置爲null來釋放其引用——這個作法叫作解除引用(dereferencing)
function createPerson(name){ var localPerson = new Object(); localPerson.name = name; return localPerson; } var globalPerson = createPerson("Nicholas"); globalPerson = null; //手工解除globalPerson的引用
解除一個值得引用並不意味着自動回收該值所佔用的內存。解除引用的真正做用是讓值脫離執行環境,以便垃圾收集器下次運行時將其回收