這篇文章將為大家詳細講解有關JavaScript中內(nèi)存空間、賦值和深淺拷貝的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
JavaScript的內(nèi)存空間
在JavaScript中,每一個數(shù)據(jù)都需要一個內(nèi)存空間。內(nèi)存空間分為兩種,棧內(nèi)存(stack)與堆內(nèi)存(heap)
棧是系統(tǒng)自動分配的內(nèi)存空間,由系統(tǒng)自動釋放,堆則是動態(tài)分配的內(nèi)存,大小不定不會自動釋放。
基礎數(shù)據(jù)類型
JavaScript中的基礎數(shù)據(jù)類型,這些值都有固定的大小,保存在棧內(nèi)存中,由系統(tǒng)自動分配存儲空間在棧內(nèi)存空間的值,我們可以直接進行操作,因此基礎數(shù)據(jù)類型都是按照值訪問
在棧內(nèi)存中的數(shù)據(jù)發(fā)生復制的行為時,系統(tǒng)會自動為新變量開辟一個新的內(nèi)存空間,當復制執(zhí)行后,兩個內(nèi)存空間的值就互不影響,改變其中一個不會影響另一個
棧內(nèi)存空間數(shù)據(jù)復制示例 var a = `I am variable a`; var b = a; console.log(b); //`I am variable a` b = `I am variable b`; console.log(a); //`I am variable a` console.log(b); //`I am variable b`
引用數(shù)據(jù)類型
引用類型的值是保存在堆內(nèi)存中的對象,在JavaScript中我們不能直接操作對象的堆內(nèi)存空間。因為引用類型的值都是按引用訪問的,所以在操作對象時,實際上是操作對象的引用而不是實際的對象。引用可以理解為保存在棧內(nèi)存中的一個地址,該地址指向堆內(nèi)存中的一個實際對象
引用類型值的復制,系統(tǒng)會為新的變量自動分配一個新的棧內(nèi)存空間這個棧內(nèi)存空間保存著與被復制變量相同的指針,盡管他們在棧內(nèi)存中的內(nèi)存空間的位置互相獨立但是在堆內(nèi)存中訪問到的對象實際上是同一個,因此,當我們改變其中一個對象的值時,實際上就是改變原來的對象
棧內(nèi)存空間保存指針(地址),堆內(nèi)存空間保存實際的對象,我們通過變量訪問對象時,實際上訪問的是對象的引用(地址)
內(nèi)存中的棧區(qū)域存放變量(基本類型的變量包括變量聲明和值)以及指向堆區(qū)域存儲位置的指針(引用類型的變量包括變量聲明和指向內(nèi)容的指針)
var a = { name : `I am object a`, type : 'object' } var b = a; console.log(b); // {name: "I am object a", type: "object"} b.name = `I am object b`; console.log(a); // {name: "I am object b", type: "object"} console.log(b); // {name: "I am object b", type: "object"}
基本類型總結
基本數(shù)據(jù)類型:
包括:null、undefined、number、string、boolean、symbol(es6)
存放位置:內(nèi)存中的棧區(qū)域中
比較:值的比較,判斷是否相等,如果值相等,就相等。一般使用===進行比較,因為==會進行類型的轉(zhuǎn)換
拷貝:賦值(通過(=)賦值操作符 賦值),賦值完成后,兩個變量之間就沒有任何關系了,改變其中一個變量的值對另一個沒有任何影響
引用類型總結
引用數(shù)據(jù)類型:
包括:數(shù)組、對象、函數(shù)
存放位置:內(nèi)存的棧區(qū)域中存放變量和指針,堆區(qū)域存儲實際的對象
比較:是引用的比較(就是地址的比較,變量在棧內(nèi)存中對應的指針地址相等就指向同一個對象)判斷是否為同一個對象,示例如下
變量a和變量b的引用不同,對象就不是同一個對象 var a = {name:'Jay'}; var b = {name:'Jay'}; a===b //false
我們對JavaScript中引用類型進行操作的時候,都是操作其對象的引用(保存在棧內(nèi)存中的指針)
賦值、深拷貝和淺拷貝 (Assignment, deep copy and shallow copy)
賦值:兩個變量的值(指針)都指向同一個對象,改變其中一個,另一個也會受到影響
所謂拷貝就是復制,通過復制原對象生成一個新的對象
淺拷貝:重新在堆內(nèi)存中開辟一個空間,拷貝后新對象獲得一個獨立的基本數(shù)據(jù)類型數(shù)據(jù),和原對象共用一個原對象內(nèi)的引用類型數(shù)據(jù),改變基本類型數(shù)據(jù),兩個對象互不影響,改變其中一個對象內(nèi)的引用類型數(shù)據(jù),另一個對象會受到影響
var obj = { name: 'Jay Chou', age: 32, song:{ name:'發(fā)如雪', year:2007 } } var obj1 = obj; function shallowCopy(obj){ var scObj = {}; for(var prop in obj){ if(obj.hasOwnProperty(prop)){ scObj[prop] = obj[prop] } } return scObj; } var obj2 = shallowCopy(obj); console.log(obj === obj1,'obj === obj1','賦值'); console.log(obj === obj2,'obj === obj2','淺拷貝'); // true "obj === obj1" "賦值" // false "obj === obj2" "淺拷貝" console.log(obj.song === obj2.song); //true obj2.song.name='雙截棍'; obj2.name='Jay'; console.log(obj) // {name: "Jay Chou", age: 32, song: {name:'雙截棍',year:2007}} console.log(obj1); // {name: "Jay Chou", age: 32, song: {name:'雙截棍',year:2007}} console.log(obj2); {name: "Jay", age: 32, song: {name:'雙截棍',year:2007}} console.log(obj===obj1) //true console.log(obj===obj2) //false
深拷貝:不論是對象內(nèi)的基本類型還是引用類型都被完全拷貝,拷貝后兩個對象互不影響
一種比較簡單實現(xiàn)方法是使用var dcObj = JSON.parse(JSON.stringify(obj))
var obj = { name: 'Jay Chou', age: 32, song:{ name:'發(fā)如雪', year:2007 } } var dcObj=JSON.parse(JSON.stringify(obj)); console.log(dcObj); // {name: "Jay Chou", age: 32, song: {name:'發(fā)如雪',year:2007}} console.log(dcObj.song === obj.song); //false dcObj.name='Jay'; dcObj.song.name='雙截棍'; console.log(obj); // {name: "Jay Chou", age: 32, song: {name:'發(fā)如雪',year:2007}} console.log(dcObj); //{name: "Jay", age: 32, song: {name:'雙截棍',year:2007}}
比較:賦值、深拷貝、淺拷貝
賦值:新對象仍然指向原對象,改變新對象的基本類型和引用類型的值都會使原對象對應的值一同改變
淺拷貝:改變新對象基本類型的值不會使原對象對應的值一起改變,但是改變新對象引用類型的值會使原對象對應的值一同改變
深拷貝:改變新對象基本類型和引用類型的值,都不會影響原對象,兩者互相獨立,互不影響
關于“JavaScript中內(nèi)存空間、賦值和深淺拷貝的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
分享文章:JavaScript中內(nèi)存空間、賦值和深淺拷貝的示例分析-創(chuàng)新互聯(lián)
轉(zhuǎn)載源于:http://vcdvsql.cn/article38/ceohsp.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、App設計、搜索引擎優(yōu)化、網(wǎng)站維護、微信小程序、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容