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

基本類型和引用類型#

ECMAScript包含兩種不同的數(shù)據(jù)類型:基本類型值和引用類型值;

  • 基本類型值指的是保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段,null,undefined,Boolean,Number和String都是基本數(shù)據(jù)類型,它們都是按值訪問的,因?yàn)榭梢圆僮鞅4嬖谧兞恐械膶?shí)際值;

  • 引用類型值(對(duì)象、數(shù)組、函數(shù)、正則):指的是那些保存在堆內(nèi)存中的對(duì)象,變量中保存的實(shí)際上只是一個(gè)指針,這個(gè)指針執(zhí)行內(nèi)存中的另一個(gè)位置,由該位置保存對(duì)象

  • 值得注意的是:string雖然屬于基本類型,但是由于自身只讀的原因,是無法修改的,這導(dǎo)致給相同的字符串賦不同的變量,不同的變量指向了同一個(gè)字符串的位置,在這點(diǎn)上有點(diǎn)類似引用類型.

<h2>JS的內(nèi)存空間</h2>
這里兩篇文章有利于理解js的內(nèi)存空間問題
博客園文章
內(nèi)存空間圖解

<h2>深淺拷貝</h2>
在Javascript 中,將一個(gè)對(duì)象賦值給一個(gè)變量其實(shí)只是將這個(gè)對(duì)象的引用拷貝了一份;
<h4>淺拷貝:</h4>
主要針對(duì)對(duì)象等引用類型
所謂淺拷貝,個(gè)人理解就是簡(jiǎn)單的拷貝了引用關(guān)系,指針指向依然是指向堆內(nèi)存中的同一個(gè)存儲(chǔ)地址,這樣當(dāng)我們改變一個(gè)對(duì)象的屬性的時(shí)候,另一個(gè)對(duì)象的屬性也跟著改變了(因?yàn)閷?shí)質(zhì)只是對(duì)象的名稱改變了,指向沒有改變,或者說實(shí)質(zhì)上的鍵值對(duì)并沒有改變)
舉例說明:
var a = {name :"frank"}; b = a;//將a的值(存放指向堆內(nèi)存中內(nèi)容的地址指針)拷貝給b b.name = "jack"; a.name === "jack";//這種情況就是淺拷貝,當(dāng)改變b的屬性時(shí),a的屬性也會(huì)跟著發(fā)生改變

<h4>深拷貝</h4>
所謂深拷貝,個(gè)人理解就是將被拷貝對(duì)象的所有內(nèi)容完全復(fù)制,并在堆內(nèi)存中開辟了一個(gè)新的內(nèi)存空間來存放,這個(gè)時(shí)候拷貝對(duì)象和被拷貝對(duì)象是完全獨(dú)立的兩個(gè)變量,當(dāng)拷貝對(duì)象或者被拷貝對(duì)象的內(nèi)容發(fā)生改變時(shí),并不會(huì)互相影響;
沿用上面的例子:
var a = {name :"frank"}; b = a;//將a的值(存放指向堆內(nèi)存中內(nèi)容的地址指針)拷貝給b b.name = "jack"; a.name === "jack";//這種情況就是淺拷貝,當(dāng)改變b的屬性時(shí),a的屬性也會(huì)跟著發(fā)生改變 b = deepClone(a);//利用深拷貝函數(shù)拷貝a,這個(gè)時(shí)候就a,b就是兩個(gè)獨(dú)立的變量,互不影響 b.name ="jack"; a,name = "frank";

知乎專欄關(guān)于深淺拷貝文章

<h1>復(fù)習(xí)部分</h1>

<h2>1.引用類型有哪些?非引用類型有哪些</h2>

  • 非引用類型有基本數(shù)據(jù)類型,基本數(shù)據(jù)類型指的是保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段;
  • 引用類型值一般有對(duì)象,數(shù)組,函數(shù)及正則表達(dá)式,指的是保存在堆內(nèi)存中的對(duì)象,變量中保存的實(shí)際上是一個(gè)指針(地址),指向了引用類型的實(shí)際值;

<h2>2.如下代碼輸出什么?為什么</h2>


  //簡(jiǎn)單分析
  //1.利用對(duì)象字面量(文本代碼)方法構(gòu)造兩個(gè)對(duì)象obj1及obj2
//2.obj1 == obj2, obj1與obj2存放的地址應(yīng)該不一致,所以是不等的
//3.console.log(obj1 == obj2)輸出應(yīng)該為false;
/*4.將obj2中的地址賦給了obj1,此時(shí)兩者存放的指針指向的儲(chǔ)值地址應(yīng)該是一致的*/
//5.console.log(obj1 = obj2),輸出的應(yīng)該是obj2對(duì)象的鍵值對(duì);
//6.console.log(obj1 == obj2),地址一致,輸出應(yīng)該是true

與分析是一致的;

<h2>3.如下代碼輸出什么? 為什么</h2>

  • 1.定義4個(gè)變量,分別為整型,對(duì)象,以及數(shù)組;

  • 2.又定義4個(gè)變量,其中aa,bb數(shù)值為單純復(fù)制1,2
    cc與c的存儲(chǔ)指針指向一致,dd與d存儲(chǔ)的指針指向一致;

    1. a,b存儲(chǔ)的值分別變?yōu)?1,22;
      c.name改變,相應(yīng)的cc.name也會(huì)改變,因?yàn)榇尜A的指針指向是一致的
      d[2]['age'] = 3 相當(dāng)于改變了下標(biāo)為2的數(shù)組對(duì)象的age屬性值為3,即c.age=3同時(shí)cc.age=3;
  • 4.console.log(aa)輸出為1

  • 5.console.log(bb)輸出為2

  • 6.console.log(cc)輸出為Object{
    name:'hello',
    age:3
    };

  • 7.console.log(dd)輸出為array[
    0:1
    1:2;
    2:object{
    name:"hello",
    age: 3
    }
    ];

<h2>4.如下代碼輸出什么? 為什么</h2>

  • 聲明并定義變量a,b,分別為整型及對(duì)象;
  • 聲明兩個(gè)函數(shù)f1及f2;
  • 調(diào)用f1(),傳入?yún)?shù)a,a=1;
  • function f1(n){
    var n = a;//相當(dāng)于單純復(fù)制了值;
    ++n;//n變?yōu)榱?1,但是對(duì)a并沒有影響;
    }
  • 調(diào)用f2(),傳入?yún)?shù)c,c存貯指向?qū)嶋H值地址的指針;
  • function f2(c){
    var obj = c;//變量obj存儲(chǔ)指針一致
    ++obj.age//相當(dāng)于c.age+1
    }
  • console.log(a),輸出1;
  • console.log(c),輸出:
    object{
    name:"饑人谷",
    age:3
    };

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

 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);
            filter(arr);
        }
    }
 }
 filter(arr);
 console.log(arr);//[3,1,2]

<h2>6.過濾如下數(shù)組,只保留正數(shù),原數(shù)組不變,生成新數(shù)組</h2>

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

<h2>7.寫一個(gè)深拷貝函數(shù),用兩種方式實(shí)現(xiàn)</h2>

  • 第一種
    var person={
    name:"wuyanwen",
    age: 24
    };
    function deepCopy(oldObj) {
    var newObj = {};
    for(var key in oldObj) {
    if(typeof oldObj[key] === 'object') {
    newObj[key] = deepCopy(oldObj[key]);
    }else{
    newObj[key] = oldObj[key];
    }
    }
    return newObj;
    }
    var newPerson = deepCopy(person)
    newPerson.name = "wuyanwen24";
    console.log(person.name);
    console.log(newPerson.name);

  • 第二種
    var person={
    name:"wuyanwen",
    age: 24
    };
    function copy(obj){
    var newobj = JSON.parse(JSON.stringify(obj));
    return newobj;
    }
    var newPerson = copy(person);
    newPerson.name = "wuyanwen24";
    console.log(person.name);
    console.log(newPerson.name);

最后編輯于
?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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