摘要:地址傳遞引用類型則是地址傳遞,將存放在棧內(nèi)存中的地址賦值給接收的變量。即對(duì)象的淺拷貝會(huì)對(duì)主對(duì)象進(jìn)行拷貝,但不會(huì)復(fù)制主對(duì)象里面的對(duì)象。
相關(guān)知識(shí)點(diǎn)
1.javascript變量包含兩種不同數(shù)據(jù)類型的值:基本類型和引用類型。
基本類型值指的是簡單的數(shù)據(jù)段,包括es6里面新增的一共是有6種,具體如下:number、string、boolean、null、undefined、symbol。
引用類型值指那些可能由多個(gè)值構(gòu)成的對(duì)象,只有一種如下:object。
在將一個(gè)值賦給變量時(shí),解析器必須確定這個(gè)值是基本類型值還是引用類型值。
2.javascript的變量的存儲(chǔ)方式:棧(stack)和堆(heap)。
棧:自動(dòng)分配內(nèi)存空間,系統(tǒng)自動(dòng)釋放,里面存放的是基本類型的值和引用類型的地址
堆:動(dòng)態(tài)分配的內(nèi)存,大小不定,也不會(huì)自動(dòng)釋放。里面存放引用類型的值。
基本數(shù)據(jù)類型是按值訪問的,因?yàn)榭梢圆僮鞅4嬖谧兞恐械膶?shí)際的值。
引用類型的值是保存在內(nèi)存中的對(duì)象。JavaScript 不允許直接訪問內(nèi)存中的位置,也就是說不能直接操作對(duì)象的內(nèi)存空間。 在操作對(duì)象時(shí), 實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。
基本類型與引用類型最大的區(qū)別實(shí)際就是 傳值與傳址 的區(qū)別
值傳遞:基本類型采用的是值傳遞。
地址傳遞:引用類型則是地址傳遞,將存放在棧內(nèi)存中的地址賦值給接收的變量。
被復(fù)制對(duì)象的所有變量都含有與原來的對(duì)象相同的值,而所有的對(duì)其他對(duì)象的引用仍然指向原來的對(duì)象。即對(duì)象的淺拷貝會(huì)對(duì)“主”對(duì)象進(jìn)行拷貝,但不會(huì)復(fù)制主對(duì)象里面的對(duì)象?!崩锩娴膶?duì)象“會(huì)在原來的對(duì)象和它的副本之間共享。
基本數(shù)據(jù)類型Number(賦值操作)
let a=1; let b=a; b //1 b=2; b //2 a //1
數(shù)組
let arr1 = [1,2,3]; let arr2 = arr1; arr2 //[1,2,3] arr2.push(4); arr2 //[1,2,3,4] arr1 //[1,2,3,4]
首先棧內(nèi)存arr1會(huì)指向堆內(nèi)存里的數(shù)組,棧內(nèi)存的arr1保存的是數(shù)組的引用,也就相當(dāng)于內(nèi)存地址,arr2=arr1,會(huì)把a(bǔ)rr1的引用賦給arr2,所以arr2也有了數(shù)組的引用,此時(shí)arr1和arr2指向的是同一個(gè)數(shù)組,因此一個(gè)數(shù)組的改變會(huì)影響另一個(gè)數(shù)組的值。
對(duì)象
let obj1={count:1,name:"grace",age:1}; let obj2 = obj1; obj2 //{count:1,name:"grace",age:1} obj2.count=2; obj1 //{count:2,name:"grace",age:1} obj2 //{count:2,name:"grace",age:1}
綜上所述,如果是基本數(shù)據(jù)類型,直接進(jìn)行賦值操作,這樣就相當(dāng)于在棧內(nèi)存中重新開辟了一個(gè)新的空間把值傳遞過去;如果是引用類型的值傳遞,進(jìn)行的就是淺拷貝,淺拷貝賦值的只是對(duì)象的引用,如上述obj2=obj1,實(shí)際上傳遞的只是obj1的內(nèi)存地址,所以obj2和obj1指向的是同一個(gè)內(nèi)存地址,所以這個(gè)內(nèi)存地址中值的改變對(duì)obj1和obj2都有影響。
深拷貝深拷貝不僅將原對(duì)象的各個(gè)屬性逐個(gè)復(fù)制出去,而且將原對(duì)象各個(gè)屬性所包含的對(duì)象也依次采用深復(fù)制的方法遞歸復(fù)制到新對(duì)象上,所以對(duì)一個(gè)對(duì)象的修改并不會(huì)影響另一個(gè)對(duì)象。
數(shù)組
法一:for循環(huán)
let arr1 = [1,2,3]; let arr2 = copyArr(arr1); function copyArr(arr){ let res=[]; for(let i=0,length=arr.length;i法二: slice
用數(shù)組自身的方法,slice、concat方法在運(yùn)行后會(huì)返回新的數(shù)組
let arr1 = [1,2,3]; let arr2 = arr1.slice(0);法三: concat
let arr1 = [1,2,3]; let arr2 = arr1.concat();法四:擴(kuò)展運(yùn)算符
let arr1 = [1,2,3]; let [...arr2] = arr1;法五:Array.from
如果參數(shù)是一個(gè)真正的數(shù)組,Array.from會(huì)返回一個(gè)一模一樣的新數(shù)組
let arr1 = [1,2,3]; let arr2 = Array.from(arr1);對(duì)象
法一:for循環(huán)
let obj1={count:1,name:"grace",age:1}; let obj2 = copyObj(obj){ let res = {}; for(let key in obj){ res[key]=obj[key]; } return res; }法二:利用JSON
let obj1={count:1,name:"grace",age:1}; let obj2 = JSON.parse(JSON.stringify(obj1));//使用JSON比較簡單,但是JSON的深拷貝方式會(huì)忽略函數(shù)對(duì)象和原型對(duì)象(有待考證)
法三:擴(kuò)展運(yùn)算符
let obj1={count:1,name:"grace",age:1}; let {...obj2} = obj1;合成版,可以實(shí)現(xiàn)數(shù)組和對(duì)象的深拷貝function deepCopy(obj){ let result = Array.isArray(obj)?[]:{}; if(obj && typeof obj === "object"){ for(let key in obj){ if(obj.hasOwnProperty(key)){ if(obj[key]&&typeof obj[key]==="object"){ result[key]=deepCopy(obj[key]); }else{ result[key]=obj[key]; } } } } return result; }注意:ES6新增了Object.assign() 方法
第一個(gè)參數(shù)是目標(biāo)對(duì)象,之后還可以跟一個(gè)或多個(gè)源對(duì)象。它會(huì)遍歷一個(gè)或多個(gè)源對(duì)象可枚舉的自有鍵并把它們復(fù)制到目標(biāo)對(duì)象,最后返回目標(biāo)對(duì)象
assign是使用=操作符來賦值,Object.assign() 只是一級(jí)屬性復(fù)制,比淺拷貝多深拷貝了一層而已。用的時(shí)候,還是要注意這個(gè)問題的
作者:優(yōu)雅1217
來源:CSDN
原文:https://blog.csdn.net/baidu_3...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/102430.html
摘要:而堆內(nèi)存主要負(fù)責(zé)像對(duì)象這種變量類型的存儲(chǔ),如下圖引用類型中復(fù)制淺拷貝的只是棧內(nèi)存中的指針,指向同一個(gè)堆內(nèi)存的對(duì)象如何實(shí)現(xiàn)深拷貝最簡單的方法就是與方法 淺拷貝只會(huì)在引用類型中出現(xiàn) 基本數(shù)據(jù)類型有哪些,number,string,boolean,null,undefined,symbol以及未來ES10新增的BigInt(任意精度整數(shù))七類。 引用數(shù)據(jù)類型(Object類)有常規(guī)名值對(duì)的無...
摘要:深拷貝和淺拷貝問題的本質(zhì)還是不同數(shù)據(jù)類型的存儲(chǔ)方式差異,尤其是引用數(shù)據(jù)類型的特殊。 深拷貝和淺拷貝問題的本質(zhì)還是不同數(shù)據(jù)類型的存儲(chǔ)方式差異,尤其是引用數(shù)據(jù)類型的特殊。showImg(https://segmentfault.com/img/bVbb8XH?w=1058&h=409); 現(xiàn)分別對(duì)賦值、淺拷貝、深拷貝做深入研究: 1.賦值 原理:直接將對(duì)象指針直接賦值給另一個(gè)變量 代碼: ...
摘要:相信人很多學(xué)習(xí)的過程中都踩了深拷貝和淺拷貝的坑,深拷貝和淺拷貝的區(qū)別我就不再贅述了,今天我來寫一下我自己實(shí)現(xiàn)深拷貝的各種方法。中的深拷貝也是用類似方法實(shí)現(xiàn)。 相信人很多學(xué)習(xí)js的過程中都踩了深拷貝和淺拷貝的坑,深拷貝和淺拷貝的區(qū)別我就不再贅述了,今天我來寫一下我自己實(shí)現(xiàn)深拷貝的各種方法。 比較簡單的拷貝方式可以借用瀏覽器的Json對(duì)象去實(shí)現(xiàn),先把對(duì)象轉(zhuǎn)化為json字符串,在解析回對(duì)...
摘要:中的深拷貝與淺拷貝說到深淺拷貝的時(shí)候就不得不說一下中的變量類型了基本類型按值存放在棧內(nèi)存中的簡單數(shù)據(jù)段可以直接訪問引用類型存放在堆內(nèi)存中的對(duì)象變量保存的是一個(gè)指向存放數(shù)據(jù)位置的指針訪問引用類型的值時(shí)首先從棧中獲取到存放該數(shù)據(jù)位置的指針然后再 JS中的深拷貝與淺拷貝 說到深淺拷貝的時(shí)候就不得不說一下JS中的變量類型了: 基本類型: undefined、null、boolean、numb...
摘要:期深拷貝與淺拷貝的區(qū)別如何實(shí)現(xiàn)一個(gè)深拷貝在回答這個(gè)問題前,我們先來回顧一下中兩大數(shù)據(jù)類型基本類型引用類型基本類型基本類型就是值類型存放在棧內(nèi)存中的簡單數(shù)據(jù)段,數(shù)據(jù)大小確定,內(nèi)存空間大小可以分配引用類型引用類型存放在堆內(nèi)存中的對(duì)象,變量實(shí)際保 20190311期 深拷貝與淺拷貝的區(qū)別?如何實(shí)現(xiàn)一個(gè)深拷貝 在回答這個(gè)問題前,我們先來回顧一下JS中兩大數(shù)據(jù)類型 基本類型 Undefined...
閱讀 3255·2021-09-10 10:51
閱讀 3448·2021-08-31 09:38
閱讀 1764·2019-08-30 15:54
閱讀 3194·2019-08-29 17:22
閱讀 3283·2019-08-26 13:53
閱讀 2036·2019-08-26 11:59
閱讀 3343·2019-08-26 11:37
閱讀 3373·2019-08-26 10:47