0

私がやろうとしているのは、別のメソッドを呼び出して取得した別のオブジェクトから x 個のプロパティと y 個のプロパティを持つオブジェクトを作成することです。これは可能ですか?

つまり、これが私の擬似コードです。基本的に、getMoreData() から返されたオブジェクトのすべてのプロパティを mydata に含めたいのですが、おそらくこれは不可能ですが、それが :(

var mydata = 
{
    name: "Joe Soap",
    dob: "01-01-2001",
    otherData: {
        hasCat: true,
        hasDog : false
    }

    var otherData = getMoreData();
    for(var prop in otherData)
    {
        create additional property in mydata for prop;
    }
}

function getMoreData()
{
    var moreData = 
    {
        middleName: "tom",
        location: "uk"
    }
    return otherData;
}
4

2 に答える 2

0

nnnnnnの回答に加えて。上記は浅いコピーのみを行うことに注意してください。

つまりObject、参照によってコピーされます。

これは、もう少し高度なマージ機能です。後でもう少し詳しく説明します。

マージ機能


var merge = (function () {
    var initThis = this;
    return function () {
        var len = arguments.length - 1,
            srt, tmp;
        if ("function" === typeof arguments[arguments.length - 1]) srt = arguments[arguments.length - 1];
        else {
            srt = function (a, b, prop) {
                if (null === prop) return a;
                return a[prop];
            };
            len++;
        }
        var merge = this === initThis ? {} : this;
        for (var i = 0; i < len; i++) inner(arguments[i], merge);

        function inner(obj2, obj1) {
            var type = ({}).toString.call(obj2);
            if (type == "[object Object]") {
                if (!obj1) obj1 = {};
                if (typeof obj1 != "object") obj1 = (tmp = srt(obj1, obj2, null), tmp) === obj2 ? {} : tmp; //If obj2 is returned, set to empty obj to allow deep cloning
                for (var prop in obj2) {
                    var isObj = "object" === typeof obj2[prop];
                    if (!obj1[prop] && isObj) obj1[prop] = inner(obj2[prop]);
                    else if (obj1[prop] && isObj) obj1[prop] = inner(obj2[prop], obj1[prop]);
                    else if (obj1[prop]) obj1[prop] = srt(obj1, obj2, prop) || obj1[prop];
                    else obj1[prop] = obj2[prop];
                }
            } else if (type == "[object Array]") {
                if (!obj1) obj1 = [];
                if (typeof obj1 != "object") obj1 = (tmp = srt(obj1, obj2, null), tmp) === obj2 ? [] : tmp
                for (var i = 0; i < obj2.length; i++) if (!obj1[i] && typeof obj2[i] == "object") obj1[i] = inner(obj2[i]);
                    else if (obj1[i] && typeof obj2[i] == "object") obj1[i] = inner(obj2[i], obj1[i]);
                else if (obj1[i]) obj1[i] = (function (i) {
                        return srt(obj1, obj2, i)
                    })(i) || obj1[i];
                else obj1[i] = obj2[i];
            }
            return obj1;
        }
        return merge;
    };
})();

サンプルデータ


var target = {
    unique: "a",
    conflict: "target",
    object: {
        origin: "target"
    },
    typeConflict: "primitive",
    arr: [1, 5, 3, 6]
};
var mergeFrom = {
    other: "unique",
    conflict: "mergeFrom",
    object: {
        origin: "mergeFrom",
        another: "property"
    },
    typeConflict: ["object"],
    arr: [3, 2, 7, 1]
};

使用法


マージ関数はnパラメーターを受け入れます。

そして、渡されたすべてのオブジェクトを 1 つにマージして返します。

.callオブジェクトがマージさ れるコンテキストを設定できます。

conflict関数は最後の引数として渡すことができます。プロパティが既に存在する場合に呼び出されます。

3 つのパラメーターで呼び出されます。

abpropここで

aは最初のオブジェクト bです。2 番目のオブジェクト propは現在マージされているプロパティです。

タイプの競合がある場合。たとえば、値 1 は aprimitiveで、値 2 は an です。Object

propnull


呼び出しの例


スコープ以外のコンテキストでマージ関数を呼び出すと、オブジェクトがマージされます。

merge.call(target,mergeFrom)

bそれを呼び出して、常にオブジェクトプロパティを使用する競合関数を渡します。

var result = merge(target,mergeFrom,function (a,b,prop) {  
    if (prop === null) return b  
    return b[prop]  
})

3 つの配列と、値を最初の配列にプッシュする競合関数を渡して呼び出す

var mergedArr = merge({arr:[1]},{arr:[2]},{arr:[3]},function (a,b,prop) {
  if (a[prop] != b[prop]) a.push(b[prop])
  return a[prop]
})

JSBinの例を次に示します。

出力


例 1 -console.log(target)

{
    "arr": [1, 5, 3, 6],
    "as": "arguments",
    "conflict": "target",
    "more": "Objects",
    "object": {
        "another": "property",
        "origin": "target"
    },
    "other": "unique",
    "typeConflict": "primitive",
    "unique": "a"
}

例 2 -console.log(result)

{
    "arr": [3, 2, 7, 1],
    "conflict": "mergeFrom",
    "object": {
        "another": "property",
        "origin": "mergeFrom"
    },
    "other": "unique",
    "typeConflict": ["object"],
    "unique": "a"
}

例 3 -console.log(mergedArr)

{
    "arr": [1, 2, 3]
}
于 2013-04-05T10:13:25.397 に答える
0

forオブジェクト リテラルの途中で、変数を宣言したり、他のステートメントを使用したりすることはできません。最初に基本オブジェクトを定義してから、後でプロパティを追加する必要があります。

var mydata = {
    name: "Joe Soap",
    dob: "01-01-2001",
    otherData: {
        hasCat: true,
        hasDog : false
    }
};

var otherData = getMoreData();
for(var prop in otherData) {
    mydata[prop] = otherData[prop];
}

また、関数は変数ではなく変数getMoreData()を返す必要があります。moreDataotherData

function getMoreData() {
    var moreData = {
        middleName: "tom",
        location: "uk"
    }
    return moreData;
}

デモ: http://jsfiddle.net/nnnnnn/TQf5H/

于 2013-04-05T09:26:51.587 に答える