摘要:實(shí)現(xiàn)合并對(duì)象的方法有很多種,比如也是用寫的,謝謝系列等,至于區(qū)別自己看文檔,文檔地址打造的一個(gè)不可變數(shù)據(jù)結(jié)構(gòu)庫(kù)的方法其中,為原生方法,但是存在以下兩個(gè)在具體應(yīng)用場(chǎng)景上的缺點(diǎn)瀏覽器兼容性問(wèn)題只能進(jìn)行淺合并關(guān)于淺合并深合并,碼友之述備矣,這里就
javascript實(shí)現(xiàn)合并對(duì)象的方法有很多種,比如:
1、Object.assign
2、jQuery.extend(jQuery也是用javascript寫的,謝謝)
3、lodash系列(lodash.merge、lodash.assign等,至于區(qū)別自己看文檔,文檔地址:https://lodash.com/docs)
4、Immutable.js(fackbook打造的一個(gè)不可變數(shù)據(jù)結(jié)構(gòu)JS庫(kù))的 merge 方法
其中,Object.assign為javascript原生方法,但是存在以下兩個(gè)在具體應(yīng)用場(chǎng)景上的缺點(diǎn):
1、瀏覽器兼容性問(wèn)題
2、只能進(jìn)行淺合并(關(guān)于淺合并深合并,碼友之述備矣,這里就不贅言,戳:https://juejin.im/entry/58df4...)
PS: 之所以說(shuō)具體應(yīng)用場(chǎng)景的缺點(diǎn),是因?yàn)榧偃珥?xiàng)目是在高版本瀏覽器運(yùn)行,并且只要對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行淺合并,那就不存在上述兩個(gè)問(wèn)題
而為了實(shí)現(xiàn)合并對(duì)象,特意引入上述的 jQuery、lodash、immutable這些庫(kù),就有點(diǎn)夸張了(項(xiàng)目本身需要用到這些庫(kù),那當(dāng)我什么也沒(méi)說(shuō))
好了,進(jìn)入正題,下面是我自己實(shí)現(xiàn)的一個(gè)可配置的合并多個(gè)對(duì)象的方法
function EXT(options) { return new EXT.prototype.init(options); } EXT.fn = EXT.prototype = { type: function(o) { return Object.prototype.toString.call(o).slice(8, -1).toLowerCase(); }, typeMap: { object: function() { return {}; }, array: function() { return []; } }, // 默認(rèn)配置項(xiàng) defaults: { // 是否深合并 isDeep: true, // 是否遍歷合并源對(duì)象原型鏈上的屬性 includePrototype: true, // 用于對(duì)每個(gè)合并項(xiàng)進(jìn)行自定義修正 forEach: function(target, name, sourceItem) { target[name] = sourceItem; return target; } }, // 將配置項(xiàng)合并到默認(rèn)配置項(xiàng) init: function(options) { for (let name in options) { this.defaults[name] = options[name]; } return this; }, merge: function() { let self = this, _default = self.defaults, i = 1, length = arguments.length, target = arguments[0] || {}, source, targetItem, sourceItem, tiType, siType, clone, name; for (; i < length; i++) { // 判斷源對(duì)象是否為空 if ((source = arguments[i]) != null) { for (name in source) { const hasPro = source.hasOwnProperty(name); // 是否遍歷源對(duì)象的原型鏈 if (hasPro || _default.includePrototype) { targetItem = target[name]; sourceItem = source[name]; tiType = self.type(targetItem); siType = self.type(sourceItem); // 防止出現(xiàn)回環(huán) if (target === sourceItem) { continue; } // 如果復(fù)制的是對(duì)象或者數(shù)組 if (_default.isDeep && sourceItem != null && self.typeMap[siType]) { clone = targetItem != null && tiType === siType ? targetItem : self.typeMap[siType](); // 遞歸 target[name] = self.merge(clone, sourceItem); } else { clone = hasPro ? target : target.__proto__; // 處理每一個(gè)合并項(xiàng) clone = _default.forEach.call(self, clone, name, sourceItem); } } } } } return target; } }; EXT.fn.init.prototype = EXT.fn;
擼個(gè)demo先,先定義兩份數(shù)據(jù)
function Foo() { this.a = 1; } function Bar() { this.c = 3; } Foo.prototype.b = 2; Bar.prototype.d = 4; let data = { info: { name: "Leslie", age: 26, scores: [60, 66, 70, 80] } }; let data2 = { info: { name: "Leslie", age: 32, scores: [99, 66, 70, { name: "john", age: 18 }, new Foo()] } };
1、普通合并
let target = EXT().merge(data1, data2);
結(jié)果為:
2、自定義配置進(jìn)行合并
isDeep:選擇是否進(jìn)行深合并,設(shè)置為 false 則只進(jìn)行淺合并,默認(rèn)為 true
let target = EXT({ isDeep: false }).merge(data1, data2);
includePrototype:選擇是否要遍歷對(duì)象的原型鏈,默認(rèn)為 true
let target = EXT({ includePrototype: false }).merge(data1, data2);
forEach:對(duì)每個(gè)合并項(xiàng)進(jìn)行自定義處理
let target = EXT({ forEach: function(target, name, sourceItem) { target[name] = sourceItem + ’hello, 自定義每個(gè)合并項(xiàng)‘; return target; } }).merge(data1, data2);
好了,這就是這個(gè)方法的全部,還不知道怎么用的小伙伴可以私信我.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/88963.html
摘要:使用構(gòu)造函數(shù)的原型繼承相比使用原型的原型繼承更加復(fù)雜,我們先看看使用原型的原型繼承上面的代碼很容易理解。相反的,使用構(gòu)造函數(shù)的原型繼承像下面這樣當(dāng)然,構(gòu)造函數(shù)的方式更簡(jiǎn)單。 五天之前我寫了一個(gè)關(guān)于ES6標(biāo)準(zhǔn)中Class的文章。在里面我介紹了如何用現(xiàn)有的Javascript來(lái)模擬類并且介紹了ES6中類的用法,其實(shí)它只是一個(gè)語(yǔ)法糖。感謝Om Shakar以及Javascript Room中...
摘要:添加元素到數(shù)組合并兩個(gè)數(shù)組錯(cuò)誤方法應(yīng)該用方法,將被的數(shù)組當(dāng)成參數(shù)數(shù)組。會(huì)改變數(shù)組,返回最新屬性,占用內(nèi)存較少。 一、Array.prototype.concat() concat方法將創(chuàng)建一個(gè)新的數(shù)組,然后將調(diào)用它的對(duì)象(this指向的對(duì)象)中的元素以及所有參數(shù)中的數(shù)組類型的參數(shù)中的元素以及非數(shù)組類型的參數(shù)本身按照順序放入這個(gè)新數(shù)組,并返回該數(shù)組。concat方法并不修改調(diào)用它的對(duì)象...
摘要:它將返回目標(biāo)對(duì)象。該方法使用源對(duì)象的和目標(biāo)對(duì)象的,所以它會(huì)調(diào)用相關(guān)和。注意,會(huì)跳過(guò)那些值為或的源對(duì)象。合并對(duì)象注意目標(biāo)對(duì)象自身也會(huì)改變。注意,只有字符串的包裝對(duì)象才可能有自身可枚舉屬性。,第三個(gè)源對(duì)象更是不會(huì)被拷貝到的。 Object.assign() Object.assign()方法用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象。它將返回目標(biāo)對(duì)象。 語(yǔ)法 Object.a...
摘要:不過(guò)的實(shí)現(xiàn)中,多了很多細(xì)節(jié)上的判斷,比如第一個(gè)參數(shù)是否是布爾值,是否是一個(gè)對(duì)象,不傳參數(shù)時(shí)的默認(rèn)值等。 JavaScritp 專題系列第七篇,講解如何從零實(shí)現(xiàn)一個(gè) jQuery 的 extend 函數(shù) 前言 jQuery 的 extend 是 jQuery 中應(yīng)用非常多的一個(gè)函數(shù),今天我們一邊看 jQuery 的 extend 的特性,一邊實(shí)現(xiàn)一個(gè) extend! extend 基本用...
摘要:深拷貝淺拷貝淺拷貝淺拷貝只是復(fù)制了內(nèi)存地址,如果原地址中的對(duì)象改變了,淺拷貝出來(lái)的對(duì)象也會(huì)相應(yīng)改變。也就是深拷貝之后,不管這個(gè)對(duì)象原來(lái)的構(gòu)造函數(shù)是什么,在深拷貝之后都會(huì)變成。 JavaScript深拷貝、淺拷貝 淺拷貝:淺拷貝只是復(fù)制了內(nèi)存地址,如果原地址中的對(duì)象改變了,淺拷貝出來(lái)的對(duì)象也會(huì)相應(yīng)改變。 深拷貝:開辟了一塊新的內(nèi)存存放地址和地址指向的對(duì)象,原地址的任何對(duì)象改變了,深拷...
閱讀 1371·2021-11-04 16:09
閱讀 3606·2021-10-19 11:45
閱讀 2473·2021-10-11 10:59
閱讀 1073·2021-09-23 11:21
閱讀 2839·2021-09-22 10:54
閱讀 1217·2019-08-30 15:53
閱讀 2676·2019-08-30 15:53
閱讀 3537·2019-08-30 12:57