內存問題是 JavaScript 比較底層的東西,依葫蘆畫瓢學會了怎麼使用變量,可是對於內存的概念依然模糊,今天讓咱們一塊兒來了解一下內存在這門語言是怎麼樣的存在。前端
內存在不一樣類型的數值面前表現有很大的不一樣。咱們把值賦給一個變量,解析器必須肯定這個值是什麼類型,先來了解變量的兩個類型:程序員
基本類型:簡單的數據段:Undefined、Null、Boolean、Number、String,按值訪問,能夠直接操做實際的值。算法
引用類型:保存在內存中的對象:Object、Array。。JavaScript 賦值保存着對象的某個變量時,操做的是對象的引用;在爲對象添加屬性的時候,操做的是實際的對象。瀏覽器
複製基本類型的數據時,計算機會從新分配一個位置給新的變量;可是複製引用類型的數據,計算機只是複製了一個指針,指向原有的對象。因此改變其中一個引用類型數據的屬性時,訪問另外一個引用類型數據的屬性能獲得同樣的結果,好比:bash
複製基本類型並改變其中一個變量:微信
let a = 20;
let b = a;
b = 30;
console.log(a) // 20
複製代碼
複製引用類型並改變其中一個變量的屬性:函數
let m = {a:10, b:20};
let n = m;
n.a = 15;
console.log(m.a) // 15
複製代碼
m,n 都指向一個引用類型的對象,因此改變 n 的屬性會致使 m 的屬性改變。上面表示的是變量之間基本的複製,可是注意:** 在全部函數的參數傳遞中,都是按值傳遞的,不是按照引用傳遞的 **。好比:源碼分析
function setName(obj){
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
let person = new Object();
setName(person);
alert(person.name); // "Nicholas"
複製代碼
JS 內存空間分爲棧(stack)、堆(heap)、池(通常也會歸類爲棧中)。其中「棧」存放基本類型變量,遵循後進先出的原則;「堆」存放引用類型,堆存取數據的方式,則與書架與書很是類似,知道名字就能取出來用;池存放常量。性能
檢測一個變量是否是基本類型,用 typeof 操做符就能夠搞定,可是這個操做符在遇到對象或者 null 時,返回 Object,咱們不知道具體的類型。這時候,用 instanceof 來確認是什麼類型的對象。學習
再也不用到的內存,沒有及時釋放,就叫作內存泄露。
大多數語言提供自動內存管理,減輕程序員的負擔,這被稱爲「垃圾回收機制」(garbage collector)。原理很簡單:找出那些再也不繼續使用的變量,而後釋放其佔用的內存。
JavaScript 具備自動垃圾收集機制,不用程序員操太多心。而不一樣的瀏覽器可能會採起不一樣的回收策略,現代瀏覽器最經常使用的方式是標記清除,其次是引用計數。
function(){
let a = new Object();
let b = new Object();
a.oneObject = b;
b.anotherObject = a;
}
複製代碼
上面的代碼中,a 和 b 經過各自的屬性實現相互引用,二者的被引用次數都是 2 。若是採用標記清楚策略,因爲函數執行結束,這兩個對象都離開了做用域,都會被清除。可是,採用引用計數策略,a 和 b 都還繼續存在,由於他們的引用次數永遠不會是 0。此時,只有手動斷開引用。
function(){
let a = new Object();
let b = new Object();
a.oneObject = b;
b.anotherObject = a;
// 消除循環:
a.oneObject = null
b.anotherObject = null;
}
複製代碼
歡迎你們關注微信公衆號:** 可視化技術( visteacher )**
不只有前端和可視化,還有算法、源碼分析、書籍相送
我的網站:blog.kurryluo.com
各個分享平臺的 KurryLuo 都是在下。
用心學習,認真生活,努力工做!