成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS專題之深淺拷貝

ASCH / 1707人閱讀

摘要:在之前的文章專題之數(shù)據(jù)類型和類型檢測中我有講過,中的數(shù)據(jù)類型分為兩種,基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型是保存在棧的數(shù)據(jù)結構中的是按值訪問,所以不存在深淺拷貝問題。

前言

在開發(fā)過程中,偶爾會遇到這種場景,拿到一個數(shù)據(jù)后,你打算對它進行處理,但是你又希望拷貝一份副本出來,方便數(shù)據(jù)對比和以后恢復數(shù)據(jù)。

那么這就涉及到了 JS 中對數(shù)據(jù)的深淺拷貝問題,所謂深淺拷貝,淺拷貝的意思就是,你只是復制了對象數(shù)據(jù)的引用,并沒有把內(nèi)存里的值另外復制一份,那么深拷貝就是把值完整地復制一份新的值。

在之前的文章《JS專題之數(shù)據(jù)類型和類型檢測》中我有講過,JS 中的數(shù)據(jù)類型分為兩種,基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型是保存在棧的數(shù)據(jù)結構中的,是按值訪問,所以不存在深淺拷貝問題。

而比如對象,數(shù)組,函數(shù),正則,時間對象這些都是引用數(shù)據(jù)類型,是保存在堆中的。所以,引用數(shù)據(jù)類型的復制,是內(nèi)存地址的傳遞,并沒有拷貝出一份新的數(shù)據(jù)。

那么深拷貝,淺拷貝的區(qū)別是什么呢?先給結論:

操作拷貝之后的數(shù)據(jù)不會影響到原數(shù)據(jù)的值拷貝,就是深拷貝,反正,有影響則為淺拷貝。
一、應用場景

日常開發(fā)中,JS 拷貝大多會在 數(shù)據(jù)保存,數(shù)據(jù)比對,數(shù)據(jù)同步 時出現(xiàn),所以,當你在這些場景的時候,要記得里面隱藏有一個數(shù)據(jù)深淺拷貝的問題。

二、淺拷貝

我們來看一下淺拷貝:

function clone(origin) {
    var result = {};
        for (var prop in origin) {
            if (origin.hasOwnProperty(prop)) {
                result[prop] = origin[prop];
            }
        }
        return result;
}

var jay = {
    name: "jayChou",
    age: 40,
    family: {
        wife: "Quinlivan"
    }
}

var otherJay = clone(jay);

otherJay.age = 18;
otherJay.family.wife = "otherGirl";

console.log(jay); 
// 
// {
//   name: "jayChou",
//   age: 40,  // 沒被改變
//   family: {
//     wife: "otherGirl"  // 同時被改變,說明是同一個引用
//   }
// }

console.log(otherJay);

// 
// {
//   name: "jayChou",
//   age: 18,
//   family: {
//     wife: "otherGirl"  // 被改變了
//   }
// }

我們發(fā)現(xiàn),首先,淺拷貝不是直接賦值,淺拷貝新建了一個對象,然后將源對象的屬性都一一復制過來,復制的是值,而不是引用。

我們知道,對象都是按地址引用進行訪問的,淺拷貝的復制只復制了第一層的屬性,并沒有遞歸將所有的值復制過來,所以,操作拷貝數(shù)據(jù),對原數(shù)據(jù)產(chǎn)生了影響,故而為淺拷貝。

進而,那些可以直接返回原數(shù)組的方法就可以簡單實現(xiàn)數(shù)組和對象淺拷貝。

// 1、 數(shù)組淺拷貝 - slice
function shallowCopy1(origin) {
    return origin.slice();
}

// 2、 數(shù)組淺拷貝 - concat
function shallowCopy2(origin){
    return origin.concat();
}

// 3、 數(shù)組淺拷貝 - 遍歷
function shallowCopy3(origin){
  var result = [];
  for(var i = 0; i < origin.length; i++) {
    result.push(origin[i]);
  }
  return result;
}


// 4、 對象淺拷貝 - Object.assign
function shallowCopy4(origin) {
    return Object.assign({},origin)
}

// 5、 對象淺拷貝 - 擴展運算符
// 擴展運算符(...)用于取出參數(shù)對象的所有可遍歷屬性,拷貝到當前對象之中
function shallowCopy5(origin) {
    return {
        ...origin
    }
}

Object.assign 的拷貝,假如源對象的屬性值是一個指向對象的引用,它也只拷貝那個引用值。MDN 有相應的實例和解釋。

二、深拷貝
深拷貝就完整復制數(shù)據(jù)的值(而非引用),目的在于避免拷貝后數(shù)據(jù)對原數(shù)據(jù)產(chǎn)生影響。

目前深拷貝的實現(xiàn)方法主要有遞歸復制,JSON 正反序列化:

// 1. 深拷貝 - JSON 正反序列化
// 缺點就是無法拷貝 undefined、function、symbol 這類特殊的屬性值。
function deepClone1(origin) {
    return JSON.parse(JSON.stringify(arr));
}

// 2. 深拷貝 - 遞歸;
function deepClone2(origin) {
  const result = origin.constructor === Array ? [] : {};
  for (let keys in origin) {
    // 不遍歷原型鏈上的屬性
    if (origin.hasOwnProperty(keys)) {
      if (origin[keys] && typeof origin[keys] === "object") {
        // 如果值是對象,就遞歸一下, 區(qū)分是一般對象還是數(shù)組對象
        result[keys] = origin[keys].constructor === Array ? [] : {};
        // 如果是引用數(shù)據(jù)類型,會遞歸調(diào)用
        result[keys] = deepClone(origin[keys]);
      } else {
        // 如果不是,就直接賦值
        result[keys] = origin[keys];
      }
    }
  }
  return result;
}

JS 的深拷貝的應用,需要根據(jù)你的使用場景進行使用,首先是有無必要深拷貝,其次是數(shù)據(jù)類型,是否直接使用 JSON 的 API 其實就可以。

JS 深淺拷貝在日常開發(fā)中使用頻率還是較高的,其中考察的知識點,主要在于:

1、是否遇到過深淺拷貝的問題,里面有什么坑
2、是否了解 JS 的數(shù)據(jù)類型,數(shù)據(jù)在計算機中的存儲機制
3、是否了解數(shù)組、對象的一些常用的 API
4、jquery、lodash、underscore 的相關工具函數(shù)使用

總結

深淺拷貝主要考察了開發(fā)者對 JS 數(shù)據(jù)類型的了解,數(shù)組,對象常用方法的特點和應用,遞歸函數(shù)的封裝。

春節(jié)快樂!  
寫于大年三十,不寫文章渾身不舒服~

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/101529.html

相關文章

  • JavaScript專題深淺拷貝

    摘要:專題系列第六篇,講解深淺拷貝的技巧和以及實現(xiàn)深淺拷貝的思路前言拷貝也是面試經(jīng)典吶數(shù)組的淺拷貝如果是數(shù)組,我們可以利用數(shù)組的一些方法比如返回一個新數(shù)組的特性來實現(xiàn)拷貝。所以我們可以看出使用和是一種淺拷貝。 JavaScript 專題系列第六篇,講解深淺拷貝的技巧和以及實現(xiàn)深淺拷貝的思路 前言 拷貝也是面試經(jīng)典吶! 數(shù)組的淺拷貝 如果是數(shù)組,我們可以利用數(shù)組的一些方法比如:slice、co...

    RancherLabs 評論0 收藏0
  • JavaScript專題系列文章

    摘要:專題系列共計篇,主要研究日常開發(fā)中一些功能點的實現(xiàn),比如防抖節(jié)流去重類型判斷拷貝最值扁平柯里遞歸亂序排序等,特點是研究專題之函數(shù)組合專題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實現(xiàn)模式需求我們需要寫一個函數(shù),輸入,返回。 JavaScript 專題之從零實現(xiàn) jQuery 的 extend JavaScritp 專題系列第七篇,講解如何從零實現(xiàn)一個 jQuery 的 ext...

    Maxiye 評論0 收藏0
  • 復習Javascript專題(四):js中的深淺拷貝

    摘要:基本數(shù)據(jù)類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對,這類引用類型數(shù)據(jù)。它會拋棄對象的。另外,查資料過程中還看到這么一個詞結構化克隆算法還有這一篇資料也有參考,也寫得比較詳細了的深淺拷貝 基本數(shù)據(jù)類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對于字符串來說,是值的復制,而對于對象來說則是對對象地址的復制;而深拷貝的話,它不...

    MobService 評論0 收藏0
  • JavaScript專題系列20篇正式完結!

    摘要:寫在前面專題系列是我寫的第二個系列,第一個系列是深入系列。專題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 專題系列是我寫的第二個系列,第一個系列是 JavaScript 深入系列。 JavaScript 專題系列共計 20 篇,主要研究日常開發(fā)中一些功能點的實現(xiàn),比如防抖、節(jié)流、去重、類型判斷、拷貝、最值、扁平、柯里...

    sixleaves 評論0 收藏0
  • javascript深淺拷貝

    摘要:為何寫最近在研究深淺拷貝,找了很多資料,感覺不是很滿意,所以自己就整理了一份。深拷貝如果給放到新的內(nèi)存中,將的各個屬性都復制到新內(nèi)存里,就是深拷貝。安全的值是指能夠呈現(xiàn)為有效格式的值。參考文檔冴羽的專題之深淺拷貝深拷貝與淺拷貝的實現(xiàn) 為何寫: 最近在研究深淺拷貝,找了很多資料,感覺不是很滿意,所以自己就整理了一份。廢話不多說,我們來一起復習一下吧,也希望留下您寶貴意見。 何為深淺拷貝?...

    LMou 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<