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

JavaScript?對(duì)象合并方法詳解及最佳實(shí)踐

 更新時(shí)間:2026年02月08日 08:45:21   作者:DEMO派  
在JavaScript開(kāi)發(fā)中,對(duì)象和數(shù)組的操作非常頻繁,這篇文章主要介紹了JavaScript對(duì)象合并方法詳解及最佳實(shí)踐的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、常用對(duì)象合并方法

1.1 展開(kāi)運(yùn)算符 (Spread Operator)

const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const result = { ...obj1, ...obj2 };
// { a: 1, b: 3, c: 4 }

優(yōu)點(diǎn)

  • 語(yǔ)法簡(jiǎn)潔直觀

  • ES6+ 原生支持

  • 創(chuàng)建新對(duì)象,不影響原對(duì)象

缺點(diǎn)

  • 淺拷貝(嵌套對(duì)象只復(fù)制引用)

  • 無(wú)法合并復(fù)雜結(jié)構(gòu)(如數(shù)組、特殊對(duì)象)

  • 不支持深度合并

1.2 Object.assign()

const obj1 = { a: 1, b: { x: 1 } };
const obj2 = { b: { y: 2 }, c: 3 };
const result = Object.assign({}, obj1, obj2);
// { a: 1, b: { y: 2 }, c: 3 } // 注意:b.x 被覆蓋

優(yōu)點(diǎn)

  • ES5+ 兼容性好

  • 可合并多個(gè)對(duì)象

  • 創(chuàng)建新對(duì)象(當(dāng)?shù)谝粋€(gè)參數(shù)為{}時(shí))

缺點(diǎn)

  • 淺拷貝

  • 會(huì)覆蓋同名屬性

  • 無(wú)法處理getter/setter

1.3 手動(dòng)深度合并函數(shù)

function deepMerge(target, ...sources) {
    if (!sources.length) return target;
    const source = sources.shift();
    
    if (isObject(target) && isObject(source)) {
        for (const key in source) {
            if (isObject(source[key])) {
                if (!target[key]) Object.assign(target, { [key]: {} });
                deepMerge(target[key], source[key]);
            } else {
                Object.assign(target, { [key]: source[key] });
            }
        }
    }
    return deepMerge(target, ...sources);
}

function isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item);
}

const obj1 = { a: 1, b: { x: 1, y: 2 } };
const obj2 = { b: { y: 3, z: 4 }, c: 5 };
const result = deepMerge({}, obj1, obj2);
// { a: 1, b: { x: 1, y: 3, z: 4 }, c: 5 }

優(yōu)點(diǎn)

  • 可深度合并

  • 高度可定制

  • 控制合并策略

缺點(diǎn)

  • 需要自己實(shí)現(xiàn)和維護(hù)

  • 可能性能較低

  • 需考慮循環(huán)引用

1.4 structuredClone() 方法

const obj1 = { 
    a: 1, 
    b: { 
        x: 1,
        nested: { deep: 'value' }
    },
    c: [1, 2, 3],
    date: new Date(),
    map: new Map([['key', 'value']]),
    set: new Set([1, 2, 3])
};

// 深度克隆
const cloned = structuredClone(obj1);

// 合并使用示例
const obj2 = { b: { y: 2 }, d: 4 };
const result = { ...structuredClone(obj1), ...obj2 };
// 或手動(dòng)合并克隆后的對(duì)象
const merged = Object.assign(structuredClone(obj1), obj2);

優(yōu)點(diǎn)

  • 真正的深度克?。òㄇ短讓?duì)象)

  • 支持復(fù)雜類(lèi)型:Date、Map、Set、ArrayBuffer等

  • 官方標(biāo)準(zhǔn),現(xiàn)代瀏覽器原生支持

  • 處理循環(huán)引用

  • 不共享任何引用

缺點(diǎn)

  • 不能克隆函數(shù)、DOM節(jié)點(diǎn)、Error對(duì)象等

  • 性能開(kāi)銷(xiāo)較大(特別是大對(duì)象)

  • Node.js 17+ 和現(xiàn)代瀏覽器才支持

  • 不能自定義合并策略

  • 只能克隆,需要配合其他方法實(shí)現(xiàn)合并

1.5 Lodash 的 merge/mergeWith

// 需要安裝 lodash
import { merge, mergeWith } from 'lodash';

const obj1 = { a: 1, b: { x: 1 } };
const obj2 = { b: { y: 2 }, c: 3 };
const result = merge({}, obj1, obj2);
// { a: 1, b: { x: 1, y: 2 }, c: 3 }

// 自定義合并邏輯
const customizer = (objValue, srcValue) => {
    if (Array.isArray(objValue)) {
        return objValue.concat(srcValue);
    }
};
const result2 = mergeWith({}, obj1, obj2, customizer);

優(yōu)點(diǎn)

  • 功能強(qiáng)大,深度合并

  • 支持自定義合并邏輯

  • 處理各種邊緣情況

  • 社區(qū)維護(hù),穩(wěn)定可靠

缺點(diǎn)

  • 增加包體積

  • 需要引入外部庫(kù)

1.6 JSON 方法(不推薦用于合并)

const obj1 = { a: 1, b: { x: 1 } };
const obj2 = { b: { y: 2 } };
const result = JSON.parse(JSON.stringify(obj1));
Object.assign(result, obj2);
// 注意:這種方式有局限性,不處理函數(shù)、循環(huán)引用等

優(yōu)點(diǎn)

  • 簡(jiǎn)單暴力

  • 創(chuàng)建完全獨(dú)立的拷貝

缺點(diǎn)

  • 丟失函數(shù)、undefined、Symbol等

  • 無(wú)法處理循環(huán)引用

  • 性能較差

二、其他特殊場(chǎng)景方法

2.1 深度合并庫(kù):deepmerge

import deepmerge from 'deepmerge';

const obj1 = { a: 1, b: { x: 1 }, arr: [1, 2] };
const obj2 = { b: { y: 2 }, arr: [3, 4] };

// 默認(rèn)合并
const result1 = deepmerge(obj1, obj2);
// { a: 1, b: { x: 1, y: 2 }, arr: [3, 4] }

// 數(shù)組合并策略
const result2 = deepmerge(obj1, obj2, {
    arrayMerge: (target, source) => target.concat(source)
});
// { a: 1, b: { x: 1, y: 2 }, arr: [1, 2, 3, 4] }

2.2 使用 Proxy 實(shí)現(xiàn)響應(yīng)式合并

function reactiveMerge(target, source) {
    return new Proxy({...target, ...source}, {
        set(obj, prop, value) {
            console.log(`Property ${prop} changed to ${value}`);
            obj[prop] = value;
            return true;
        }
    });
}

三、方法對(duì)比

四、總結(jié)與建議

根據(jù)數(shù)據(jù)結(jié)構(gòu)和需求選擇

  • 簡(jiǎn)單對(duì)象淺合并:擴(kuò)展運(yùn)算符 {…a, …b}

  • 需要兼容舊環(huán)境:Object.assign({}, a, b)

  • 包含特殊類(lèi)型(Date、Map等)的深度克?。簊tructuredClone()

  • 復(fù)雜深度合并且已使用工具庫(kù):_.merge()

  • 完全控制合并邏輯:自定義遞歸函數(shù)

structuredClone適用場(chǎng)景

// 場(chǎng)景1:需要深度克隆包含Date、Map等特殊類(lèi)型
const config = {
  lastUpdated: new Date(),
  permissions: new Set(['read', 'write']),
  metadata: new Map()
};
const backup = structuredClone(config);

// 場(chǎng)景2:處理可能包含循環(huán)引用的對(duì)象
const objA = { name: 'A' };
const objB = { name: 'B', ref: objA };
objA.ref = objB; // 循環(huán)引用
const cloned = structuredClone(objA); // 正確處理

// 場(chǎng)景3:需要轉(zhuǎn)移數(shù)據(jù)到Worker線(xiàn)程
const largeData = { /* 大數(shù)據(jù)對(duì)象 */ };
const worker = new Worker('worker.js');
worker.postMessage(structuredClone(largeData));

現(xiàn)代項(xiàng)目最佳實(shí)踐

// 1. 創(chuàng)建工具函數(shù),根據(jù)情況選擇最佳方案
export function smartClone(obj, deep = false) {
  if (!deep) {
    return Array.isArray(obj) ? [...obj] : { ...obj };
  }
  
  // 檢查是否包含不支持的類(lèi)型
  const hasFunctions = JSON.stringify(obj, (key, value) => {
    return typeof value === 'function' ? undefined : value;
  }) === undefined;
  
  if (hasFunctions || typeof structuredClone === 'undefined') {
    // 回退到自定義深度克隆或JSON方法
    return deepCloneFallback(obj);
  }
  
  return structuredClone(obj);
}

// 2. 對(duì)象合并的通用函數(shù)
export function mergeObjects(target, source, options = {}) {
  const { deep = false, cloneStrategy = 'auto' } = options;
  
  if (!deep) {
    return { ...target, ...source };
  }
  
  if (cloneStrategy === 'structuredClone') {
    return deepMergeWithClone(target, source);
  } else if (cloneStrategy === 'json') {
    // 僅用于可序列化數(shù)據(jù)
    const cloned = JSON.parse(JSON.stringify(target));
    return deepMergeRecursive(cloned, source);
  } else {
    // 默認(rèn)使用lodash或自定義深度合并
    return deepMergeCustom(target, source, options);
  }
}

瀏覽器兼容性處理

// 特征檢測(cè)與polyfill
function safeStructuredClone(obj) {
  if (typeof structuredClone === 'function') {
    try {
      return structuredClone(obj);
    } catch (error) {
      // 處理不支持的類(lèi)型
      console.warn('structuredClone failed:', error);
      return fallbackClone(obj);
    }
  } else {
    // 降級(jí)方案
    return fallbackClone(obj);
  }
}

function fallbackClone(obj) {
  // 實(shí)現(xiàn)一個(gè)支持基本類(lèi)型的深度克隆
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  
  if (obj instanceof Date) {
    return new Date(obj);
  }
  
  if (obj instanceof Array) {
    return obj.map(item => fallbackClone(item));
  }
  
  if (obj instanceof Object) {
    const cloned = {};
    for (const key in obj) {
      if (Object.hasOwn(obj, key)) {
        cloned[key] = fallbackClone(obj[key]);
      }
    }
    return cloned;
  }
  
  // 其他類(lèi)型直接返回(包括函數(shù))
  return obj;
}

最終建議總結(jié)

  • 默認(rèn)選擇擴(kuò)展運(yùn)算符:用于大多數(shù)淺合并場(chǎng)景,語(yǔ)法簡(jiǎn)潔性能好

  • 深度合并考慮需求:優(yōu)先使用structuredClone(現(xiàn)代瀏覽器),備選lodash或自定義函數(shù)

  • 注意數(shù)據(jù)類(lèi)型:有函數(shù)時(shí)不能用structuredClone和JSON方法

  • 考慮性能:大數(shù)據(jù)量或頻繁操作時(shí)避免深度克隆

  • 做好兼容性:生產(chǎn)環(huán)境使用特征檢測(cè)和降級(jí)方案

  • 明確合并策略:特別是數(shù)組和特殊對(duì)象的處理邏輯

適用場(chǎng)景

淺合并優(yōu)先使用原生方法,深度操作評(píng)估是否需要引入庫(kù),根據(jù)實(shí)際數(shù)據(jù)結(jié)構(gòu)和性能需求選擇,保持團(tuán)隊(duì)代碼風(fēng)格統(tǒng)一。

總結(jié)

到此這篇關(guān)于JavaScript對(duì)象合并方法詳解及最佳實(shí)踐的文章就介紹到這了,更多相關(guān)JS對(duì)象合并方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JS棧stack類(lèi)的實(shí)現(xiàn)與使用方法示例

    JS棧stack類(lèi)的實(shí)現(xiàn)與使用方法示例

    這篇文章主要介紹了JS棧stack類(lèi)的實(shí)現(xiàn)與使用方法,結(jié)合實(shí)例形式分析了棧的原理,以及javascript定義與使用棧的基本操作技巧,需要的朋友可以參考下
    2019-01-01
  • JavaScript判斷DIV內(nèi)容是否為空的方法

    JavaScript判斷DIV內(nèi)容是否為空的方法

    整體思路是這樣的:判斷div內(nèi)部是否為空,如果為空,給出無(wú)數(shù)據(jù)提示;否則顯示正常頁(yè)面,下面給大家分享js判斷div內(nèi)容是否為空的方法,對(duì)判斷div內(nèi)容是否為空的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • xmlHTTP實(shí)例

    xmlHTTP實(shí)例

    xmlHTTP實(shí)例...
    2006-10-10
  • 自適應(yīng)高度框架 ----屬個(gè)人收藏內(nèi)容

    自適應(yīng)高度框架 ----屬個(gè)人收藏內(nèi)容

    自適應(yīng)高度框架 ----屬個(gè)人收藏內(nèi)容...
    2007-01-01
  • Auntion-TableSort國(guó)人寫(xiě)的一個(gè)javascript表格排序的東西

    Auntion-TableSort國(guó)人寫(xiě)的一個(gè)javascript表格排序的東西

    Auntion-TableSort國(guó)人寫(xiě)的一個(gè)javascript表格排序的東西...
    2007-11-11
  • JavaScript實(shí)現(xiàn)切換多張圖片

    JavaScript實(shí)現(xiàn)切換多張圖片

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)切換多張圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • 微信小程序如何實(shí)現(xiàn)快速精確定位

    微信小程序如何實(shí)現(xiàn)快速精確定位

    騰訊位置服務(wù)為微信小程序提供了基礎(chǔ)的標(biāo)點(diǎn)能力、線(xiàn)和圓的繪制接口等地圖組件和位置展示、地圖選點(diǎn)等地圖API位置服務(wù)能力支持,下面這篇文章主要給大家介紹了關(guān)于微信小程序如何實(shí)現(xiàn)快速精確定位的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • JS獲取本地地址及天氣的方法實(shí)例小結(jié)

    JS獲取本地地址及天氣的方法實(shí)例小結(jié)

    這篇文章主要介紹了JS獲取本地地址及天氣的方法,結(jié)合實(shí)例形式總結(jié)分析了javascript通過(guò)瀏覽器、第三方API實(shí)現(xiàn)獲取本地地址與天氣的相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • Bootstrap框架下下拉框select搜索功能

    Bootstrap框架下下拉框select搜索功能

    這篇文章主要為大家詳細(xì)介紹了Bootstrap框架下下拉框select搜索功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-07-07
  • 關(guān)于前后端json數(shù)據(jù)的發(fā)送與接收詳解

    關(guān)于前后端json數(shù)據(jù)的發(fā)送與接收詳解

    這篇文章主要給大家介紹了關(guān)于前后端json數(shù)據(jù)發(fā)送與接收的相關(guān)資料,文中通過(guò)示例代碼詳細(xì)介紹了關(guān)于flask中的json數(shù)據(jù)接收和前端發(fā)送json數(shù)據(jù)等內(nèi)容,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-07-07

最新評(píng)論

临夏市| 德格县| 城步| 玛多县| 凤翔县| 越西县| 海淀区| 锡林浩特市| 海丰县| 广汉市| 聂拉木县| 布拖县| 闻喜县| 塔河县| 垫江县| 湖口县| 芜湖市| 南康市| 卢湾区| 阿拉善盟| 临湘市| 石门县| 怀安县| 阜平县| 兴海县| 康平县| 平顺县| 延川县| 秀山| 龙口市| 正镶白旗| 长阳| 获嘉县| 南漳县| 垫江县| 沙洋县| 阿尔山市| 泽普县| 井研县| 丹江口市| 清新县|