最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js深拷貝與淺拷貝一文徹底搞懂

 更新時(shí)間:2022年04月06日 09:43:10   投稿:wdc  
這篇文章主要介紹了js深拷貝與淺拷貝一文徹底搞懂,需要的朋友可以參考下

深拷貝淺拷貝只是針對(duì)引用數(shù)據(jù)類型

JavaScript數(shù)據(jù)類型包括基本數(shù)據(jù)類型(Number,String,boolean,Null,Undefined,Symbol)、引用數(shù)據(jù)類型(Array,Object)

  • 基本數(shù)據(jù)類型的特點(diǎn):直接存儲(chǔ)在棧(stack)中的數(shù)據(jù)

  • 引用數(shù)據(jù)類在棧中存有指針,實(shí)體數(shù)據(jù)存在堆中,通過棧中的指針找到堆中的引用數(shù)據(jù)類型的實(shí)體

淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存,修改新對(duì)象不會(huì)改到原對(duì)象。

賦值和淺拷貝的區(qū)別

當(dāng)我們把一個(gè)對(duì)象賦值給一個(gè)新的變量時(shí),賦的其實(shí)是該對(duì)象的在棧中的地址,而不是堆中的數(shù)據(jù)。也就是兩個(gè)對(duì)象指向的是同一個(gè)存儲(chǔ)空間,無論哪個(gè)對(duì)象發(fā)生改變,其實(shí)都是改變的存儲(chǔ)空間的內(nèi)容,因此,兩個(gè)對(duì)象是聯(lián)動(dòng)的。

淺拷貝是按位拷貝對(duì)象,它會(huì)創(chuàng)建一個(gè)新對(duì)象,這個(gè)對(duì)象有著原始對(duì)象屬性值的一份精確拷貝。如果屬性是基本類型,拷貝的就是基本類型的值;如果屬性是內(nèi)存地址(引用類型),拷貝的就是內(nèi)存地址 ,因此如果其中一個(gè)對(duì)象改變了這個(gè)地址,就會(huì)影響到另一個(gè)對(duì)象。即默認(rèn)拷貝構(gòu)造函數(shù)只是對(duì)對(duì)象進(jìn)行淺拷貝復(fù)制(逐個(gè)成員依次拷貝),即只復(fù)制對(duì)象空間而不復(fù)制資源。

// 對(duì)象賦值
var obj1 = {
   'name' : 'zhangsan',
   'age' :  '18',
   'language' : [1,[2,3],[4,5]],
};
var obj2 = obj1;
obj2.name = "lisi";
obj2.language[1] = ["二","三"];
console.log('obj1',obj1)
console.log('obj2',obj2)

image

// 淺拷貝
var obj1 = {
   'name' : 'zhangsan',
   'age' :  '18',
   'language' : [1,[2,3],[4,5]],
};
var obj3 = shallowCopy(obj1);
obj3.name = "lisi";
obj3.language[1] = ["二","三"];
function shallowCopy(src) {
   var dst = {};
   for (var prop in src) {
       if (src.hasOwnProperty(prop)) {
           dst[prop] = src[prop];
       }
   }
   return dst;
}
console.log('obj1',obj1)
console.log('obj3',obj3)

image

上面例子中,obj1是原始數(shù)據(jù),obj2是賦值操作得到,而obj3淺拷貝得到。我們可以很清晰看到對(duì)原始數(shù)據(jù)的影響,具體請(qǐng)看下表:

image

淺拷貝的實(shí)現(xiàn)方法

1. Object.assign()

Object.assign() 方法可以把任意多個(gè)的源對(duì)象自身的可枚舉屬性拷貝給目標(biāo)對(duì)象,然后返回目標(biāo)對(duì)象。但是 Object.assign() 進(jìn)行的是淺拷貝,拷貝的是對(duì)象的屬性的引用,而不是對(duì)象本身。

對(duì)于Object.assign()而言,如果對(duì)象的屬性值為簡(jiǎn)單類型(string,number),通過Object.assign({},srcobj);得到的新對(duì)象為深拷貝;如果屬性值為對(duì)象或其他引用類型,那對(duì)于這個(gè)對(duì)象而言其實(shí)是淺拷貝

2. Array.prototype.concat()

let arr = [1, 3, {
   username: 'kobe'
}];
let arr2=arr.concat();
arr2[2].username = 'wade';
console.log(arr);

image

3. Array.prototype.slice()

let arr = [1, 3, {
   username: ' kobe'
}];
let arr3 = arr.slice();
arr3[2].username = 'wade'
console.log(arr);

image

深拷貝的實(shí)現(xiàn)

1. JSON.parse(JSON.stringify())

原理: 用JSON.stringify將對(duì)象轉(zhuǎn)成JSON字符串,再用JSON.parse()把字符串解析成對(duì)象,一去一來,新的對(duì)象產(chǎn)生了,而且對(duì)象會(huì)開辟新的棧,實(shí)現(xiàn)深拷貝。

這種方法雖然可以實(shí)現(xiàn)數(shù)組或?qū)ο笊羁截?,但不能處理函?shù)。

這是因?yàn)?JSON.stringify() 方法是將一個(gè)JavaScript值(對(duì)象或者數(shù)組)轉(zhuǎn)換為一個(gè) JSON字符串,不能接受函數(shù)

2. 手寫遞歸方法

//遞歸來實(shí)現(xiàn)深拷貝
    function deepClone(obj){
      var newObj = obj instanceof Array ? []:{};
      if(typeof obj !== 'object'){
        return obj;
      }else {
        for(var i in obj) {
          newObj[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i];
        }
      } 
      return newObj;
    }
    var q = [1, 2, 4, 6, { age: 12 }, [1, 2]];
    var d = deepClone(q)
    console.log(d)

3. 函數(shù)庫(kù)lodash

var _ = require('lodash');
var obj1 = {
   a: 1,
   b: { f: { g: 1 } },
   c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false

更多關(guān)于js深拷貝與淺拷貝的文章請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

  • 如何利用js在兩個(gè)html窗口間通信

    如何利用js在兩個(gè)html窗口間通信

    這篇文章主要介紹了如何利用js在兩個(gè)html窗口間通信,如果讀者們有類似的需求,可以參考下
    2021-04-04
  • Prototype框架詳解

    Prototype框架詳解

    Prototype是一個(gè)JavaScript框架,旨在簡(jiǎn)化動(dòng)態(tài)Web應(yīng)用程序的開發(fā)。原型被稱為作為一個(gè)單一的文件分發(fā)的prototype.js,本文給大家介紹prototype框架,感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11
  • 詳解ES6中class的實(shí)現(xiàn)原理

    詳解ES6中class的實(shí)現(xiàn)原理

    這篇文章主要介紹了詳解ES6中class的實(shí)現(xiàn)原理,幫助大家更好的理解和學(xué)習(xí)JavaScript es6,感興趣的朋友可以了解下
    2020-10-10
  • 微信小程序?qū)崿F(xiàn)tab頁(yè)面切換功能

    微信小程序?qū)崿F(xiàn)tab頁(yè)面切換功能

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)tab頁(yè)面切換功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • 關(guān)于JavaScript中異步/等待的用法與理解

    關(guān)于JavaScript中異步/等待的用法與理解

    這篇文章主要給大家介紹了關(guān)于JavaScript中異步/等待的用法與理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • JavaScript常用數(shù)組操作方法,包含ES6方法

    JavaScript常用數(shù)組操作方法,包含ES6方法

    這篇文章主要介紹了JavaScript常用數(shù)組操作方法,包含ES6方法,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • 惰性函數(shù)定義模式 使用方法

    惰性函數(shù)定義模式 使用方法

    惰性函數(shù)定義模式 使用方法...
    2007-09-09
  • javascript文本模板用法實(shí)例

    javascript文本模板用法實(shí)例

    這篇文章主要介紹了javascript文本模板用法,實(shí)例分析了文本模板的相關(guān)實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • 簡(jiǎn)單的js計(jì)算器實(shí)現(xiàn)

    簡(jiǎn)單的js計(jì)算器實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了如何實(shí)現(xiàn)簡(jiǎn)單js計(jì)算器的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • echarts實(shí)現(xiàn)餅圖與樣式設(shè)置

    echarts實(shí)現(xiàn)餅圖與樣式設(shè)置

    這篇文章介紹了echarts實(shí)現(xiàn)餅圖與樣式設(shè)置的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06

最新評(píng)論

八宿县| 蛟河市| 沂水县| 靖西县| 习水县| 西平县| 新巴尔虎左旗| 姜堰市| 清徐县| 八宿县| 泰宁县| 石台县| 福安市| 徐闻县| 天祝| 西乌珠穆沁旗| 安西县| 仲巴县| 内丘县| 玛纳斯县| 元氏县| 阳城县| 秦皇岛市| 武城县| 大田县| 安泽县| 曲水县| 新河县| 洪江市| 昔阳县| 平泉县| 天水市| 涟源市| 许昌市| 高雄县| 吉林市| 黑水县| 宜阳县| 卫辉市| 雷波县| 东辽县|