web-dev-qa-db-ja.com

Underscore.jsでの再帰/ディープ拡張/割り当て?

Underscore.jsを取得する方法はありますか extend 関数:

ソースオブジェクトのすべてのプロパティを宛先オブジェクトにコピーし、宛先オブジェクトを返します。順序が正しいため、最後のソースは前の引数の同じ名前のプロパティをオーバーライドします。

...再帰的に動作しますか?

実際、querycreditOperationプロパティは、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'
    }
}
31
gremo

いいえ、 Underscoreには深いextend は含まれません。異なる種類のオブジェクトを扱うには複雑すぎるためです。代わりに、ユーザーは、必要なものをサポートする独自のソリューションを実装することをお勧めします。

あなたの場合、それは単なるオブジェクトなので、実装は非常に簡単です:

_.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;
}
20
Bergi

Lodash (アンダースコアのフォーク)でできます。 Lodashの_。extendメソッドは、3番目(またはそれ以上)のパラメーターを関数として受け入れ、値(古いものと新しいもの)を受け取ります。したがって、次のようなことができます。

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

pd。として Paolo Moretti はコメントで述べたように、_。mergeと呼ばれるlodashに同じ関数があります

_.merge(a,b);
38
gobwas

jQueryには extend() 関数があり、対応するアンダースコアと同じことを行いますが、deep引数もあります。必要に応じて再帰的にマージできます:

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

または、baseOperationを上書きしたくない場合:

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

値がオブジェクトではなく文字列である場合の修正を含む、ベルギのディープエクステンドのスタンドアロンバージョン。また、より厳密になるようにパッチを適用しました。

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;
}
7
KrekkieD

Kurt Milamは deepExtendメソッドをunderscore.jsに追加するmixin を公開しました。正規表現も扱います(必要な場合)。ドキュメントからの抜粋:

Underscore.jsと混ぜてください:_.mixin({deepExtend: deepExtend});

次のように呼び出します:var myObj = _.deepExtend(grandparent, child, grandchild, greatgrandchild)

注:乾いた状態に保ちます。

この関数は、JSON構成ドキュメントを使用している場合に特に役立ちます。最も一般的な設定でデフォルトの設定ドキュメントを作成し、特定の場合にそれらの設定を上書きできます。引数として任意の数のオブジェクトを受け入れ、構成ドキュメント階層をきめ細かく制御できます。

2
peterp

アンダースコアのextend()は深い拡張を行いません。実際のところ、アンダースコアには深く拡張できる機能はありません。

そのためには、lodashの merge を使用できます。

1
Gaurang Patel