簡體   English   中英

Underscore.js 中的遞歸/深度擴展/分配?

[英]Recursive/deep extend/assign in Underscore.js?

有什么辦法可以得到 Underscore.js 的extend功能:

將源對象中的所有屬性復制到目標對象,並返回目標對象。 它是有序的,因此最后一個源將覆蓋先前參數中的同名屬性。

...遞歸工作?

事實上, query物業creditOperation是要完全覆蓋query中定義的屬性baseOperation

var url = require('url')
  , _ = require('underscore'),
  , baseOperation = {
        host: 'gateway.skebby.it',
        pathname: 'api/send/smseasy/advanced/http.php',
        protocol: 'https',
        query: {
            'username': 'foo',
            'password': 'bar',
        }
    };

var creditOperation = _.extend(baseOperation, {
    query: {
        'method': 'baz'
    }
});

console.log(url.format(creditOperation));

我想獲得這個creditOperation

{
    host: 'gateway.skebby.it',
    pathname: 'api/send/smseasy/advanced/http.php',
    protocol: 'https',
    query: {
        'username': 'foo',
        'password': 'bar',
        'method': 'baz'
    }
}

使用Lodash (下划線的分叉)你可以。 Lodash 的_.extend方法接受第三個(或更高)參數作為一個函數,它接收值(舊的和新的); 所以你可以做這樣的事情:

var deep = function(a, b) {
    return _.isObject(a) && _.isObject(b) ? _.extend(a, b, deep) : b;
};

var a = {a:{b:{c:1}}},
    b = {a:{b:{z:1}}};

_.extend(a,b,deep);

更新。 正如Paolo Moretti在評論中所說, lodash 中有一個相同的函數叫做_.merge

_.merge(a,b);

jQuery 有一個extend()函數,它和 Underscore 對應的做同樣的事情,但也有一個深度參數,允許它按照你的需要遞歸合並:

var creditOperation = $.extend(true, baseOperation, {
    query: {
        'method': 'baz'
    }
});

或者,如果您不想覆蓋baseOperation

var creditOperation = $.extend(true, {}, baseOperation, {
    query: {
        'method': 'baz'
    }
});

Underscore 沒有計划添加深度擴展,因為它被認為太復雜而無法處理不同類型的對象。 相反,鼓勵用戶在他們需要的支持下實施他們自己的解決方案。

在您的情況下,它只是普通對象,因此實現非常簡單:

_.deepObjectExtend = function(target, source) {
    for (var prop in source)
        if (prop in target)
            _.deepObjectExtend(target[prop], source[prop]);
        else
            target[prop] = source[prop];
    return target;
}

Bergi 深度擴展的獨立版本,包括修復值是字符串而不是對象時的問題。 還修補了更嚴格。

function deepObjectExtend (target, source) {
    for (var prop in source) {
        if (source.hasOwnProperty(prop)) {
            if (target[prop] && typeof source[prop] === 'object') {
                deepObjectExtend(target[prop], source[prop]);
            }
            else {
                target[prop] = source[prop];
            }
        }
    }
    return target;
}

Kurt Milam 發布了一個mixin,為 underscore.js 添加了deepExtend方法 它甚至處理正則表達式(如果你願意)。 文檔摘錄:

將它與 underscore.js 混合: _.mixin({deepExtend: deepExtend});

像這樣調用它: var myObj = _.deepExtend(grandparent, child, grandchild, greatgrandchild)

注意事項:保持干燥。

如果您正在處理 JSON 配置文檔,則此功能特別有用。 它允許您使用最常見的設置創建默認配置文檔,然后針對特定情況覆蓋這些設置。 它接受任意數量的對象作為參數,讓您可以對配置文檔層次結構進行細粒度控制。

下划線的擴展()不做深度擴展; 事實上,underscore 中沒有可以深度擴展的函數。

您可以為此使用 lodash 的合並

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM