js內存堆棧,遞歸原理以及淺拷貝和深拷貝的理解

敬業福還是搶不到~~還是繼續寫教程吧

js內存管理,往深了講很複雜,這裡只是淺顯的介紹,幫助你理解js的基本類型和引用類型,以及它們拷貝問題,順帶著講一下遞歸在內存的實現,幫助你了解遞歸了,以及閉包了的知識。講的不對的地方還請指正,

1、棧(stack)和堆(heap)

stack為自動分配的內存空間,它由系統自動釋放;而heap則是動態分配的內存,大小不定也不會自動釋放。       

2、基本類型和引用類型

基本類型:存放在棧內存中的簡單數據段,數據大小確定,內存空間大小可以分配。

  5種基本數據類型有Undefined、Null、Boolean、Number 和 String,它們是直接按值存放的,所以可以直接訪問。

引用類型:存放在堆內存中的對象,變數實際保存的是一個指針,這個指針指向另一個位置。每個空間大小不一樣,要根據情況開進行特定的分配。

  當我們需要訪問引用類型(如對象,數組,函數等)的值時,首先從棧中獲得該對象的地址指針,然後再從堆內存中取得所需的數據。

3.淺拷貝(賦給的是一個指針,並不是真正的值)

var o = { name :"小花", friend:[小明,小藍]}function copy(o){ var c = {}; for(var i in o){ c[i] = o[i]; } return c;}//上面的形式,我在介紹原型式繼承的時候原型式繼承也是一種淺拷貝,有興趣的看我上一篇文章,繼承和這個稍有不同,在這裡不做敘述var c1 = copy(o);c1.name = "小黑";c1.friend.push("小白");var c2 = copy(o);console.log(c2.name);//小花console.log(c2.frined);//小明,小藍小白

看一下它們的關係圖就應該清楚了

3.深度拷貝

我們不希望,修改c1的值影響,影響c2,那就不能單純的複製指針了,應該把對象的屬性也複製一遍。上酸菜

var o = { name :"小花", friend:[小明,小藍]}function copy(o,c){//c 拷貝 o 被拷貝的 var c = c || {}; for(var i in o){ if(typeof o[i] === object){ c[i] = (o[i].constructor = Array)?[]:{}; copy(o[i],c[i]); }else{ c[i] = o[i]; } } return c;}var c1 = copy(o);o.friend.push("小黑");console.log(c1.friend);//小明,小藍

通過上面的例子,可以發現實現深度的複製,o對象和c1對象,修改屬性值,已經沒有了影響,它們現在的內存關係圖是

通過上面的例子,都懂了吧

上面我們用到了遞歸,我們講解一下它的原理,以及在內存情況

舉一個栗子

var num = 5;function start(num){ if(num>3){ start(--num); } alert(num);}start(num);//調用 3 3 4

why 為什麼是3 3 4 呢,我們畫一下內存圖就明白

能看懂函數的遞歸,也就能明白函數的閉包的原理了,休息一下,過會講解閉包的原理
推薦閱讀:

前端日刊-2018.01.06
WEB前端開發人員須知的常見瀏覽器兼容問題及解決技巧
【aux】統一現有的開發工具
全面了解TCP/IP到HTTP

TAG:前端開發 | 前端工程師 |