欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中的淺拷貝和深拷貝原理與實現(xiàn)淺析

 更新時間:2023年04月21日 10:50:38   作者:葉落風(fēng)塵  
這篇文章主要介紹了JavaScript中的淺拷貝和深拷貝原理與實現(xiàn),JavaScript 中的淺拷貝和深拷貝指的是在復(fù)制對象(包括對象、數(shù)組等)時,是否只復(fù)制對象的引用地址或者在復(fù)制時創(chuàng)建一個新的對象

前言

JavaScript 中的淺拷貝和深拷貝指的是在復(fù)制對象(包括對象、數(shù)組等)時,是否只復(fù)制對象的引用地址或者在復(fù)制時創(chuàng)建一個新的對象。具體區(qū)別如下:

淺拷貝:淺拷貝只拷貝基本類型的數(shù)據(jù),而符合類型的數(shù)據(jù)只復(fù)制指向其的指針,而不復(fù)制對象本身,新舊對象還是共享同一塊內(nèi)存。這意味著如果原始對象的屬性或子對象發(fā)生更改,則復(fù)制的對象也會受到影響。常見的實現(xiàn)方式包括使用 Object.assign()方法、展開運算符(…)以及循環(huán)遍歷對象并將其屬性復(fù)制到新對象中。

深拷貝:深拷貝會另外創(chuàng)造一個一模一樣的對象,新對象跟原對象不共享內(nèi)存,修改新對象不會改到原對象。

什么是淺拷貝

當(dāng)我們進行 JavaScript 對象或數(shù)組的淺拷貝時,它只會復(fù)制其基本值的引用,而不是完全復(fù)制內(nèi)容。也就是說,淺拷貝只是復(fù)制了原始對象的屬性/元素的引用,并沒有新建一個對象。

例如,如果我們有一個簡單的對象:

const obj = { name: 'John', age: 30 };

然后我們使用對象的賦值語法來創(chuàng)建一個淺拷貝:

const newObj = obj;

此時,newObjobj 都指向同一個內(nèi)存地址。如果我們改變 newObj 的某個屬性,那么 obj 的相應(yīng)屬性也會發(fā)生改變。

newObj.age = 40;
console.log(obj.age); // 輸出 40

這是因為 newObjobj 指向的是同一個內(nèi)存地址,所以任何更改都會反映在另一個變量上。

類似地,在數(shù)組中進行淺拷貝也會產(chǎn)生相同的效果:

const arr = [1, 2, 3];
const newArr = arr;
newArr.push(4);
console.log(arr); // 輸出 [1, 2, 3, 4]

實現(xiàn)淺拷貝

淺拷貝可以使用 Object.assign() 或者展開運算符 … 來實現(xiàn);

/**
 * 淺拷貝
 *
 * @param {Object} target 目標對象
 * @param {Object} source 源對象
 * @return {Object} 返回目標對象
 */
function extend(target, source) {
    for (var key in source) {
        if (source.hasOwnProperty(key)) {
            var value = source[key];
            if (typeof value !== 'undefined') {
                target[key] = value;
            }
        }
    }
    return target;
}

什么是深拷貝

相比于淺拷貝,深拷貝會復(fù)制整個對象或數(shù)組,包括其所有的嵌套子對象和數(shù)組。這意味著新創(chuàng)建的對象與原始對象沒有任何關(guān)聯(lián),改變其中一個對象不會影響另一個。

例如,如果我們使用 JavaScript 的內(nèi)置函數(shù) JSON.parse()JSON.stringify() 來進行深拷貝:

const obj = { name: 'John', age: 30 };
const newObj = JSON.parse(JSON.stringify(obj));
newObj.age = 40;
console.log(obj.age); // 輸出 30

在這個例子中,先使用 JSON.stringify() 將原始對象序列化為字符串,再使用 JSON.parse() 將其解析為新對象。由于字符串是基本類型的值,而非引用類型,因此 newObj 是一個全新的對象,與 obj 沒有關(guān)系。

類似地,在數(shù)組中進行深拷貝也會產(chǎn)生相同的效果:

const arr = [1, [2, 3], [4, [5]]];
const newArr = JSON.parse(JSON.stringify(arr));
newArr[1][0] = 6;
console.log(arr[1][0]); // 輸出 2

在這個例子中,通過深拷貝創(chuàng)建了一個新數(shù)組,并且修改新數(shù)組中嵌套數(shù)組的元素時,原始數(shù)組并不會受到影響。

實現(xiàn)深拷貝

深拷貝可以使用 JSON.parse(JSON.stringify(obj))、遞歸復(fù)制對象屬性、第三方庫如 lodash 的 deepClone 等方式來實現(xiàn)。但需注意的是,這些方法也有可能存在一些限制和缺陷,比如不能處理函數(shù)、循環(huán)引用等問題。

function deepCopy(obj) {
    var result, copy;
    if (obj.constructor === Object)
        result = {}; //判斷傳入的如果是對象,繼續(xù)遍歷
    else if (Array.isArray(obj))
        result = []; //判斷傳入的如果是數(shù)組,繼續(xù)遍歷
    else
        return obj; //如果是基本數(shù)據(jù)類型就直接返回
    for (var key in obj) {
        if(obj.hasOwnProperty(key)){
            copy = obj[key];
            if(copy===null){
                break;
            }
            if(typeof copy ==='undefined'){
                result[key]=undefined;
            }else if (getType(copy) == "Object"||getType(copy) == "Array")
                result[key] = deepCopy(copy); //遞歸方法
            else
                result[key] = copy; //基本數(shù)據(jù)類型則賦值給屬性
        }
    }
    return result;
}
/**
* 深拷貝
* @param obj
* @param appeard
* @returns {*[]|any}
*/
deepCopy(obj, appeard = new Map()) {
    if (!(obj instanceof Object)) return obj; //如果是原始數(shù)據(jù)類型
    if (appeard.has(obj)) return appeard.get(obj); //如果已經(jīng)出現(xiàn)過
    let result = Array.isArray(obj) ? [] : {};
    appeard.set(obj, result); //將新對象放入map
    //遍歷所有屬性進行遞歸拷貝
    [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)].forEach(key => (result[key] = this.deepCopy(obj[key], appeard)));
    return result;
}

到此這篇關(guān)于JavaScript中的淺拷貝和深拷貝原理與實現(xiàn)淺析的文章就介紹到這了,更多相關(guān)Javascript深拷貝與淺拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Javascript驗證方法大全

    Javascript驗證方法大全

    這篇文章是集合了Javascript所有表單驗證方法,非常全面,感興趣的小伙伴們可以參考一下
    2015-09-09
  • window.location.href = window.location.href 跳轉(zhuǎn)無反應(yīng) a超鏈接onclick事件寫法

    window.location.href = window.location.href 跳轉(zhuǎn)無反應(yīng) a超鏈接onclic

    js下window.location.href = window.location.href 跳轉(zhuǎn)無反應(yīng) a 超鏈接 onclick 點擊跳轉(zhuǎn)無反應(yīng)問題的解決方法
    2013-08-08
  • 小程序獲取用戶名和頭像完整代碼

    小程序獲取用戶名和頭像完整代碼

    這篇文章主要介紹了關(guān)于小程序獲取用戶名和頭像的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家學(xué)習(xí)或者用小程序具有一需要的參考借鑒價值,朋友可以參考下
    2023-07-07
  • Javascript 淺拷貝、深拷貝的實現(xiàn)代碼

    Javascript 淺拷貝、深拷貝的實現(xiàn)代碼

    Javascript中的對像賦值與Java中是一樣的,都為引用傳遞.就是說,在把一個對像賦值給一個變量時,那么這個變量所指向的仍就是原來對像的地址.那怎么來做呢 答案是克隆.
    2008-12-12
  • 在iframe中使bootstrap的模態(tài)框在父頁面彈出問題

    在iframe中使bootstrap的模態(tài)框在父頁面彈出問題

    這篇文章主要介紹了在iframe中使bootstrap的模態(tài)框在父頁面彈出問題,解決方法非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-08-08
  • 老生常談JavaScript 正則表達式語法

    老生常談JavaScript 正則表達式語法

    下面小編就為大家?guī)硪黄仙U凧avaScript 正則表達式語法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • javascript實現(xiàn)秒表計時器的制作方法

    javascript實現(xiàn)秒表計時器的制作方法

    這篇文章主要為大家詳細介紹了javascript實現(xiàn)秒表計時器的制作方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • JavaScript 繼承詳解(五)

    JavaScript 繼承詳解(五)

    在本章中,我們將分析John Resig關(guān)于JavaScript繼承的一個實現(xiàn) - Simple JavaScript Inheritance,需要的朋友可以參考下
    2016-10-10
  • 前端頁面適配之postcss-px-to-viewport實現(xiàn)步驟

    前端頁面適配之postcss-px-to-viewport實現(xiàn)步驟

    postcss-px-to-viewport是一個PostCSS插件,它可以將px單位轉(zhuǎn)換為視口單位(vw、vh?或?vmin),這篇文章主要給大家介紹了關(guān)于前端頁面適配之postcss-px-to-viewport的實現(xiàn)步驟,需要的朋友可以參考下
    2024-03-03
  • php的派發(fā)機制實現(xiàn)方法

    php的派發(fā)機制實現(xiàn)方法

    PHP是一種動態(tài)類型的編程語言,它支持面向?qū)ο缶幊?在PHP中,派發(fā)指在運行時確定要調(diào)用的方法或函數(shù)的過程,派發(fā)機制允許根據(jù)實際對象的類型來選擇要執(zhí)行的方法,這種靈活性使得PHP可以實現(xiàn)多態(tài)性,本文將給大家介紹php的派發(fā)機制是怎么實現(xiàn)的,需要的朋友可以參考下
    2023-10-10

最新評論