引用類型對象拷貝

引用類型與非引用類型

ECMA Script中規(guī)定着饥,javascript的基本數(shù)據(jù)類型分為兩類,即基本數(shù)據(jù)類型和引用類型,其中基本數(shù)據(jù)類型包括5樣,number啡邑、string 贱勃、boolean、以及undefined谤逼、null兩個(gè)特殊類型,其次引用類型包括狹義的Object贵扰、Array、Function流部、正則等.

關(guān)于這兩種數(shù)據(jù)類型戚绕,他們的不同之處在于數(shù)據(jù)的保存的形式不同,對于基本類型的數(shù)據(jù)枝冀,其保存的方式是在內(nèi)存中的椢璐裕空間耘子,開辟一個(gè)固定大小的空間進(jìn)行固定位置的保存,并且數(shù)據(jù)的訪問形式是后進(jìn)先出球切,而引用類型的數(shù)據(jù)馋记,其保存的形式是在內(nèi)存的堆空間開辟一個(gè)動(dòng)態(tài)的空間保存來保存數(shù)據(jù)的值(因?yàn)閿?shù)據(jù)的大小不固定),當(dāng)我們訪問這個(gè)變量的時(shí)候其實(shí)是根據(jù)出存在椘冻龋空間的指針尋址來查找到相應(yīng)的堆內(nèi)存空間矾踱,這也就很好地解釋了為什么,當(dāng)我們給基本類型進(jìn)行重復(fù)賦值的時(shí)候鸵钝,基本數(shù)據(jù)的值不會(huì)改變糙臼,而引用類型會(huì)一起連帶改變,因?yàn)槲覀兊母淖儾辉偈菃为?dú)去創(chuàng)建一個(gè)副本恩商,而是查找了同一個(gè)指針引用并改變了其堆內(nèi)存中的值 变逃。

(string類型有些特殊,因?yàn)樽址哂锌勺兊拇笮〉】埃燥@然它不能被直接存儲(chǔ)在具有固定大小的變量中揽乱。由于效率的原因,我們希望JS只復(fù)制對字符串的引用研叫,而不是字符串的內(nèi)容锤窑。但是另一方面,字符串在許多方面都和基本類型的表現(xiàn)相似嚷炉,而字符串是不可變的這一事實(shí)(即沒法改變一個(gè)字符串值的內(nèi)容)渊啰,因此可以將字符串看成行為與基本類型相似的不可變引用類型。
)

如下代碼輸出結(jié)果及原因

var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);//兩個(gè)不同的對象儲(chǔ)存的是不同的指針申屹。false
console.log(obj1 = obj2);//將obj2賦值給obj1,就是對指針進(jìn)行復(fù)制,那么兩者的指針指向同一個(gè)堆內(nèi)存空間.
console.log(obj1 == obj2);//兩個(gè)對象的指針是相同的绘证,指向同一個(gè)內(nèi)存空間。ture

如下代碼輸出結(jié)果及原因

var a = 1
var b = 2
var c = { name: '饑人谷', age: 2 }
var d = [a, b, c]

var aa = a
var bb = b
var cc = c
var dd = d

a = 11
b = 22
c.name = 'hello'//改變c.name的值
d[2]['age'] = 3  //改變c.age的值

console.log(aa) //會(huì)輸出1
console.log(bb) //會(huì)輸出2,都是值傳遞哗讥,aa和a,bb和吧b都會(huì)開辟一個(gè)塊屬于自己的椚履牵空間
console.log(cc)//會(huì)輸出{ name: 'hello', age: 3 }對象的賦值是引用傳遞,cc和c都是指向同一塊堆內(nèi)存杆煞。
console.log(dd)//會(huì)輸出[ 11, 22, { name: 'hello', age: 3 } ]數(shù)組的賦值也是引用傳遞

如下代碼輸出結(jié)果及原因

var a = 1
var c = { name: 'jirengu', age: 2 }

function f1(n){
  ++n
}
function f2(obj){
  ++obj.age
}

f1(a)  //1 魏宽,會(huì)默認(rèn)執(zhí)行賦值動(dòng)作,var n = a,屬于值傳遞决乎,++n時(shí)队询,a依舊保持原始值不變的
f2(c)  //會(huì)默認(rèn)執(zhí)行var obj = c;這時(shí)候它們都是指向同一塊堆內(nèi)存,當(dāng)執(zhí)行++obj.age時(shí),對象c的age屬性加一构诚,所以這個(gè)時(shí)候c = {name:'jirengu',age:3}
f1(c.age) //取出c.age = 3 默認(rèn)執(zhí)行var n = 3.不會(huì)影響c.age
console.log(a) //會(huì)輸出1
console.log(c)//會(huì)輸出{ name: 'jirengu', age: 3 }

過濾如下數(shù)組蚌斩,只保留正數(shù),直接在原數(shù)組上操作

var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
    for (var i=0; i<arr.length; i++) {
        if (arr[i] <= 0) {
            arr.splice(i,1); //當(dāng)有一個(gè)數(shù)被刪除時(shí)范嘱,下一個(gè)數(shù)的index就變成了現(xiàn)在的這個(gè)值送膳。如果繼續(xù)循環(huán)就會(huì)錯(cuò)過下一個(gè)元素
            i--;
        }
    }
}
filter(arr)
console.log(arr) // [3,1,2]

過濾如下數(shù)組员魏,只保留正數(shù),原數(shù)組不變叠聋,生成新數(shù)組

var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
var newArr = []; 
var j = 0;
    for (var i=0; i<arr.length; i++) {
        if (arr[i] > 0 ) {
            newArr[j] = arr[i];
            j++;
        }
    }
    return newArr;
}
var arr2 = filter(arr)
console.log(arr2)
console.log(arr)

寫一個(gè)深拷貝函數(shù)撕阎,用兩種方式實(shí)現(xiàn).

深拷貝指的是,當(dāng)我們重新給引用類型賦值到一個(gè)新的變量的時(shí)候碌补,其所賦值的內(nèi)容不再是簡單的將地址進(jìn)行拷貝闻书,而是另外創(chuàng)建了一個(gè)棧空間脑慧,并用于保存新值的地址,這樣當(dāng)我們?nèi)ジ淖冊家玫刂返膶傩灾禃r(shí),并不會(huì)影響后續(xù)新賦值的引用類型的值,其核心思想是使用遞歸砰盐,并遞歸至基本類型變量后闷袒,再復(fù)制。

淺拷貝示例:

var obj = {
    name:'abc',
    friend:{
        name:'def',
        sex:'female'
    }
}
function shadowCopy(obj) {
    var newObj = {};
    for (var key in obj) {
        //每一項(xiàng)直接賦值岩梳,如果是引用類型就會(huì)出問題
        newObj[key] = obj[key];
    }
   return newObj;
}
var obj2 = shadowCopy(obj);
obj2.name = 'ghi';
console.log(obj);
obj2.friend.name = 'jkl';
console.log(obj);
//改變非引用類型的時(shí)囊骤,原對象不會(huì)發(fā)生變化。但是如果有引用類型時(shí)就會(huì)影響冀值,所以需要深拷貝

深拷貝示例1

function deepCopy(obj) {
    var newObj = {};
    for (var key in obj) {
        if (typeof obj[key] === 'object' || typeof obj[key] !=== 'null' ) 
                {
                       newObj[key] = deepCopy[obj[key]];    
                }
                else {
            newObj[key] = obj[key]; 
        }
    }   
    return newObj;
}

深拷貝示例2

//利用json.stringify()將對象轉(zhuǎn)換為字符串也物,然后再利用json.parse()將字符串轉(zhuǎn)換為對象
function deepCopy1(obj) {
    return newObj = JSON.parse(JSON.stringify(obj));
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市列疗,隨后出現(xiàn)的幾起案子滑蚯,更是在濱河造成了極大的恐慌,老刑警劉巖抵栈,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件告材,死亡現(xiàn)場離奇詭異,居然都是意外死亡古劲,警方通過查閱死者的電腦和手機(jī)斥赋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來产艾,“玉大人疤剑,你說我怎么就攤上這事∶票ぃ” “怎么了隘膘?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缚窿。 經(jīng)常有香客問我棘幸,道長,這世上最難降的妖魔是什么倦零? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任误续,我火速辦了婚禮吨悍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蹋嵌。我一直安慰自己育瓜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布栽烂。 她就那樣靜靜地躺著躏仇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腺办。 梳的紋絲不亂的頭發(fā)上焰手,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音怀喉,去河邊找鬼书妻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛躬拢,可吹牛的內(nèi)容都是我干的躲履。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼聊闯,長吁一口氣:“原來是場噩夢啊……” “哼工猜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起菱蔬,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤篷帅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后拴泌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犹褒,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年弛针,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叠骑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡削茁,死狀恐怖宙枷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情茧跋,我是刑警寧澤慰丛,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站瘾杭,受9級(jí)特大地震影響诅病,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一贤笆、第九天 我趴在偏房一處隱蔽的房頂上張望蝇棉。 院中可真熱鬧,春花似錦芥永、人聲如沸篡殷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽板辽。三九已至,卻和暖如春棘催,著一層夾襖步出監(jiān)牢的瞬間劲弦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工醇坝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瓶您,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓纲仍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贸毕。 傳聞我的和親對象是個(gè)殘疾皇子郑叠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 引用類型 引用類型變量保存的僅僅是一個(gè)指針乡革,指針指向堆內(nèi)存中保存對象的位置。 所以基本類型復(fù)制的時(shí)候僅僅復(fù)制值摊腋,復(fù)...
    DeeJay_Y閱讀 577評論 0 0
  • 1.引用類型有哪些沸版?非引用類型有哪些非引用類型值,即基本類型值(數(shù)值兴蒸,布爾值视粮,undefined,null):指保...
    青鳴閱讀 403評論 0 0
  • 1.引用類型有哪些橙凳?非引用類型有哪些 引用類型包括:數(shù)組蕾殴、對象、正則岛啸、函數(shù) 非引用類型(即基本類型):數(shù)值钓觉、布爾值...
    饑人谷_js_chen閱讀 271評論 0 0
  • 1.引用類型有哪些荡灾?非引用類型有哪些引用類型:對象、數(shù)組、函數(shù)批幌、正則础锐。變量中保存的是指向存儲(chǔ)數(shù)據(jù)內(nèi)容位置的指針非引...
    lingfighting閱讀 211評論 0 0
  • 1.引用類型; 2.過濾數(shù)組; 3.深淺拷貝方法; 1.引用類型有哪些?非引用類型有哪些 引用類型:引用類型(Ob...
    好奇而已閱讀 1,366評論 0 0