javascript實現一個合并多個對象的方法

來源:互聯網
上載者:User

標籤:com   tab   clone   length   pos   使用方法   let   img   end   

javascript實現合并對象的方法有很多種,比如:

1、Object.assign

2、jQuery.extend(jQuery也是用javascript寫的,謝謝)

3、lodash系列(lodash.merge、lodash.assign等,至於區別自己看文檔,文檔地址:https://lodash.com/docs)

4、Immutable.js(fackbook打造的一個不可變資料結構JS庫)的 merge 方法

 

其中,Object.assign為javascript原生方法,但是存在以下兩個在具體應用情境上的缺點:

1、瀏覽器安全色性問題

2、只能進行淺合并(關於淺合并深合并,碼友之述備矣,這裡就不贅言,戳:https://juejin.im/entry/58df4c8b61ff4b006b131792)

PS: 之所以說具體應用情境的缺點,是因為假如項目是在高版本瀏覽器運行,並且只要對資料結構進行淺合并,那就不存在上述兩個問題

 

而為了實現合并對象,特意引入上述的 jQuery、lodash、immutable這些庫,就有點誇張了(項目本身需要用到這些庫,那當我什麼也沒說)

 

好了,進入正題,下面是我自己實現的一個可配置的合并多個對象的方法

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 [];        }    },    // 預設配置項    defaults: {        // 是否深合并        isDeep: true,        // 是否遍曆合并來源物件原型鏈上的屬性        includePrototype: true,        // 用於對每個合并項進行自訂修正        forEach: function(target, name, sourceItem) {            target[name] = sourceItem;            return target;        }    },    // 將配置項合并到預設配置項    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++) {            // 判斷來源物件是否為空白            if ((source = arguments[i]) != null) {                for (name in source) {                    // 是否遍曆來源物件的原型鏈                    if (source.hasOwnProperty(name) || _default.includePrototype) {                        targetItem = target[name];                        sourceItem = source[name];                        tiType = self.type(targetItem);                        siType = self.type(sourceItem);                        // 防止出現迴環                        if (target === sourceItem) {                            continue;                        }                        // 如果複製的是對象或者數組                        if (_default.isDeep && sourceItem != null && self.typeMap[siType]) {                            clone = targetItem != null && tiType === siType ? targetItem : self.typeMap[siType]();                            // 遞迴                            target[name] = self.merge(clone, sourceItem);                        } else {                            // 處理每一個合并項                            target = _default.forEach.call(self, target, name, sourceItem);                        }                    }                }            }        }        return target;    }};EXT.fn.init.prototype = EXT.fn;

 

擼個demo先,先定義兩份資料

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);

結果為:

2、自訂配置進行合并

 isDeep:選擇是否進行深合并,設定為 false 則只進行淺合并,預設為 true

let target = EXT({ isDeep: false }).merge(data1, data2);
includePrototype:選擇是否要遍曆對象的原型鏈,預設為 true
let target = EXT({ includePrototype: false }).merge(data1, data2);

forEach:對每個合并項進行自訂處理

let target = EXT({    forEach: function(target, name, sourceItem) {        target[name] = sourceItem + ’hello, 自訂每個合并項‘;        return target;    }}).merge(data1, data2);

 

好了,這個就是這個方法的使用方法,怎麼樣?是不是很靈活?是不是很好用?

 

但是!(最怕的就是但是)這個方法還是有問題的,不知道電視機前的你發現沒有,就是合并 new Foo() 的時候,會把 Foo 原型鏈上的屬性一起拷貝到目標對象,而不是拷貝到目標對象的原型鏈

這個問題暫時沒想到解決方案,後面想到會更新上來,或者你有什麼解決方案也可以留言,幫忙解決一下,最後祝大家加班愉快!

(胖虎是我偶像)

javascript實現一個合并多個對象的方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.