這篇文章主要介紹了JS內(nèi)存生命周期,棧內(nèi)存與堆內(nèi)存,深淺拷貝是什么,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:域名申請、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、元寶山網(wǎng)站維護、網(wǎng)站推廣。
在講棧內(nèi)存與堆內(nèi)存之前,大家應該都知道JS分為兩種數(shù)據(jù)類型:
String , Number , Boolean , null , undefined , Symbol (大小固定,體積輕量,相對簡單)
Object , Array , Function (大小不一定,占用空間較大,相對復雜)
var a=true; //布爾型,基本數(shù)據(jù)類型var b='jack'; //字符型,基本數(shù)據(jù)類型var c=18; //數(shù)值型,基本數(shù)據(jù)類型var d={name:'jack'}; //對象,引用數(shù)據(jù)類型var d=[0,1,2,3,4,5]; //數(shù)組,引用數(shù)據(jù)類型復制代碼
正是因為數(shù)據(jù)類型的不同,所以他們的存放方式也不同,就和現(xiàn)實生活中窮人和富人的住所完全不一樣(扯遠了)。我們先來看一張圖:
可以看到, a
, b
, c
都是基本數(shù)據(jù)類型, d
和 e
都是引用數(shù)據(jù)類型,他們在存放方式上有著本質(zhì)性的區(qū)別,基本數(shù)據(jù)類型的值是存放在棧內(nèi)存中的,而引用數(shù)據(jù)類型的值是存放在堆內(nèi)存中的,棧內(nèi)存中僅僅存放著它在棧內(nèi)存中的引用(即它在堆內(nèi)存中的地址),就和它的名字一樣,引用數(shù)據(jù)類型
上面講的是存儲,接下來說一下變量的訪問,基本數(shù)據(jù)類型可以直接從棧內(nèi)存中訪問變量的值,而引用數(shù)據(jù)類型要先從棧內(nèi)存中找到它對應的引用地址,再拿著這個引用地址,去堆內(nèi)存中查找,才能拿到變量的值
上面已經(jīng)和大家說過了基本數(shù)據(jù)類型與引用數(shù)據(jù)類型在存儲上的不同,那么,接下來說的這個深淺拷貝,想必大家也在面試題中經(jīng)常碰到,老方式,先來看一段代碼
var name='jack';var obj={ age:24};var nameCopy=name;var objCopy=obj; nameCopy='bob'; objCopy.age=15;console.log(name); //jackconsole.log(obj.age); //15復制代碼
你會發(fā)現(xiàn), name
是沒有被影響的,而我們命名是修改objCopy.age
,為什么還會影響到 obj.age
呢,這就是因為深淺拷貝的問題在搗鬼,先來看下下面的一張圖
之所以會出現(xiàn)這種情況,是因為JS對于基本類型和引用類型的,當我們在復制引用類型的時候,復制的是該對象的引用地址,所以,在執(zhí)行 var objCopy=obj;
的時候,將 obj
的引用地址復制給了 objCopy
,所以,這兩個對象實際指向的是同一個對象,即改變 objCopy
的同時也改變了 obj
的值,我們將這種情況稱為淺拷貝,僅僅復制了對象的引用,并沒有開辟新的內(nèi)存,拿人手短,拷貝地太淺了。(只有引用類型才會出現(xiàn)淺拷貝的情況)
再來看接下來的一段代碼
var name='jack';var obj={ age:24};var nameCopy=name;var objCopy=JSON.parse(JSON.stringify(obj)); nameCopy='bob'; objCopy.age=15;console.log(name); //jackconsole.log(obj.age); //24復制代碼
可以發(fā)現(xiàn),在經(jīng)過 JSON.parse(JSON.stringify(obj))
轉(zhuǎn)換了以后,淺拷貝不復存在,這一波是深拷貝,深拷貝開辟了新的堆內(nèi)存地址,并且將對象的引用指向了新開辟的內(nèi)存地址,和前面復制的對象完全獨立,自立根生,拷貝地很深,學功夫?qū)W到家,自立門戶的感覺。
var objCopy=Object.assign({},obj); //對象深拷貝的方法 Object.assign var arrayCopy=array.concat(); //數(shù)組深拷貝的方法 concat() (數(shù)組無嵌套對象或者數(shù)組可用) var arrayCopy=array.slice(); //數(shù)組深拷貝的方法 slice() (數(shù)組無嵌套對象或者數(shù)組可用) JSON.parse(JSON.stringify(array)) //順帶提下,JSON.parse(JSON.stringify()) 數(shù)組和對象通用復制代碼
接著上面的數(shù)組容易踩坑的地方 ,來看一個例子
var array = [{name: 'jack'}, ['old']];var arrCopy = array.concat(); arrCopy[0].name='new';console.log(array); // [{name: 'new'}, ['old']]console.log(arrCopy); // [{name: 'new'}, ['old']]復制代碼
可以清楚地看到(數(shù)組無嵌套對象或者數(shù)組可用的情況下用 concat
和 slice
才有效)
感謝你能夠認真閱讀完這篇文章,希望小編分享JS內(nèi)存生命周期,棧內(nèi)存與堆內(nèi)存,深淺拷貝是什么內(nèi)容對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,遇到問題就找創(chuàng)新互聯(lián),詳細的解決方法等著你來學習!