引用類型對(duì)象拷貝

1.引用類型有哪些?非引用類型有哪些
非引用類型值,即基本類型值(數(shù)值,布爾值,undefined,null):指保存在棧內(nèi)存中的簡單數(shù)據(jù)段。
引用類型值(對(duì)象,數(shù)組,函數(shù),正則):值保存在堆內(nèi)存中的對(duì)象;變量實(shí)際保存的是一個(gè)指針,這個(gè)指針是用來指向另一個(gè)位置,該位置用來保存對(duì)象。
2.如下代碼輸出什么?為什么

var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);
console.log(obj1 = obj2);
console.log(obj1 == obj2);

結(jié)果:false ; object {a:1,b:2} ; true
obj1 == obj2是判斷兩個(gè)變量是否相等;由于對(duì)對(duì)象聲明變量,變量實(shí)際保存的是對(duì)象在內(nèi)存中的位置的指針;所以是聲明的是兩個(gè)指針,故不相等。
obj1 = obj2;是把obj2的指針賦值給obj1,同時(shí),他們指向同一塊內(nèi)存。所以,輸出obj1的值就是obj2的對(duì)象。
之前由于obj1 = obj2,把obj2的指針賦值給obj1,所以他們是相等的,結(jié)果為true。
3.如下代碼輸出什么? 為什么

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
d[2]['age'] = 3
console.log(aa) 
console.log(bb) 
console.log(cc)
console.log(dd)

結(jié)果:
aa=1;
因?yàn)閍是基本類型值,在a=11,之前,a=1的值已經(jīng)賦值給aa。
bb=2;
同理,b也是基本類型值。
cc={name:hello, age:3};
因?yàn)閏是引用類型值,所以cc=c,是把c的指針賦值給cc,令這兩個(gè)變量指向同一個(gè)內(nèi)存。故,對(duì)c的內(nèi)存的值改變,即會(huì)使cc的值發(fā)生改變。又由于d[2]['age'] = 3,即數(shù)組d的第三個(gè)值的age屬性的值變?yōu)?。直接改變的是值,而不是指針。

dd = [1, 2, {name: hello , age:3}];
同理,dd 是引用類型值,由于c.name = 'hello'd[2]['age'] = 3共同改變內(nèi)存中的值。
4.如下代碼輸出什么? 為什么

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

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

`f1(a) 
f2(c) 
f1(c.age) 
console.log(a) 
console.log(c)

結(jié)果:
a=1;
執(zhí)行函數(shù)f1(a),在f1(n)函數(shù)中,發(fā)生了,var n = a,所以++n實(shí)際上是n=++n,并沒有對(duì)a的值做出改變。故a=1。
{name:'jirengu',age:3};
當(dāng)執(zhí)f2(c)時(shí),在f2(obj)函數(shù)中,發(fā)生了,var obj=c,即c變量是把指針賦值給obj了,令這兩個(gè)變量指向同一個(gè)內(nèi)存。當(dāng)++obj.age,執(zhí)行的是對(duì)age屬性的值加1,故變量c的指針指向的內(nèi)存的值發(fā)生改變。
當(dāng)執(zhí)行f1(c.age)時(shí),在1(n)函數(shù)中,發(fā)生了,var n=c.age,

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

1.利用push() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的末尾,并返回?cái)?shù)組的新長度。

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

2.利用splice() 方法通過刪除現(xiàn)有元素來更改數(shù)組的內(nèi)容。注意,如果添加進(jìn)數(shù)組的元素個(gè)數(shù)不等于被刪除的元素個(gè)數(shù),數(shù)組的長度會(huì)發(fā)生相應(yīng)的改變。

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);//添加0個(gè)元素,刪除一個(gè),length發(fā)生改變。
            i--;
        }
    }
return
}
filter(arr)
console.log(arr)

6.過濾如下數(shù)組,只保留正數(shù),原數(shù)組不變,生成新數(shù)組
定義新的數(shù)組,就會(huì)有新的指針,遍歷原數(shù)組到新數(shù)組即可。

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

7.寫一個(gè)深拷貝函數(shù),用兩種方式實(shí)現(xiàn)
淺拷貝:只拷貝對(duì)象的基本類型值,如果某一個(gè)屬性是引用類型值,拷貝的就是這個(gè)引用類型的指針。當(dāng)原對(duì)象的引用類型值發(fā)生改變,則淺拷貝后的新對(duì)象的引用類型值也會(huì)發(fā)生改變,但非引用類型值不變。

深拷貝:拷貝對(duì)象的所有屬性,無論是引用類型值還是非引用類型值,拷貝之后的新對(duì)象,與原對(duì)象沒有任何關(guān)系。
1、用遞歸實(shí)現(xiàn)深拷貝

var obj = {
        name: 'ruoyu',
        sex: 'male',
        age: 30,
        friend: {
            name: 'hello', 
            age: 100
        }
    };
function deepCopy(oldObj){
    var newObj = {};
    for(var key in oldObj){
        if(typeof oldObj[key]==='number'||typeof oldObj[key]==='string'||
        typeof oldObj[key]==='boolean'||oldObj[key]=== 'undefined'
        ||oldObj[key]=== 'null'){
            newObj[key] = oldObj[key] ;
        }else
        {
            newObj[key] = deepCopy(obj[key]);
        }
    }
    return newObj;
}

var obj2 = deepCopy(obj);
obj.friend.age = 10;
console.log(obj2)

其實(shí)是否是深拷貝,還與obj.friend.age = 10;var obj2 = deepCopy(obj);相對(duì)順序有關(guān),如果是

obj.friend.age = 10;
var obj2 = deepCopy(obj);
console.log(obj2)

則對(duì)obj.friend.age重新賦值,再執(zhí)行函數(shù),則是淺拷貝,實(shí)際運(yùn)用中當(dāng)注意這點(diǎn)。

(typeof oldObj[key]==='number'||typeof oldObj[key]==='string'||
        typeof oldObj[key]==='boolean'||oldObj[key]=== 'undefined'
        ||oldObj[key]=== 'null')

即使引用類型值包括函數(shù)、正則,用這種基本類型值判斷,同樣可以深拷貝。
2、
使用JSON

function deepCopy(obj){
    var newObj=JSON.stringify(obj)
    var newObj1 = JSON.parse(newObj);
    return newObj1;
}

注意:
復(fù)合類型的值只能是數(shù)組或?qū)ο?,不能是函?shù)、正則表達(dá)式對(duì)象、日期對(duì)象。
簡單類型的值只有四種:字符串、數(shù)值(必須以十進(jìn)制表示)、布爾值和null(不能使用NaN, Infinity, -Infinity和undefined)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.引用類型有哪些?非引用類型有哪些 非引用類型值,即基本類型值(數(shù)值,布爾值,undefined,null):指...
    LINPENGISTHEONE閱讀 254評(píng)論 0 0
  • 1.引用類型有哪些?非引用類型有哪些2.如下代碼輸出什么?為什么? var obj1 = {a:1, b:2}; ...
    Rising_suns閱讀 290評(píng)論 0 0
  • 1.引用類型有哪些?非引用類型有哪些 基本類型值(Number、Boolean、string、null和undef...
    saintkl閱讀 398評(píng)論 0 0
  • .引用類型 & 非引用類型 引用類型值(對(duì)象、數(shù)組、函數(shù)、正則):指的是那些保存在堆內(nèi)存中的對(duì)象,變量中保存的實(shí)際...
    邢烽朔閱讀 411評(píng)論 0 0
  • 引用類型有哪些?非引用類型有哪些 基本類型值(Undefined、Null、Boolean、Number和Stri...
    jamesXiao_閱讀 196評(píng)論 0 0

友情鏈接更多精彩內(nèi)容