2017-04-21 9 views
2

背景(Object.update()またはjQuery.extend()は解決策ではなく、なぜこれは、他のどのツーコピー-javascriptのオブジェクトの質問の重複しない理由):forループgetters/setterを保存しているときにJavascriptオブジェクトをシャローコピーする方法はありますか?

を使用して、 コピーのこのバージョン

myobj.fullname === 'fname lname' // true 
myobj.fullname = 'Anton' 
myobj.fullname === 'Anton lname' // true 
すなわち

var myobj = { 
    _fname: 'fname', 
    _lname: 'lname', 
    get fullname() { return this._fname + ' ' + this._lname; }, 
    set fullname(v) { this._fname = v; } 
}; 

function copy_obj(obj) { 
    var copy = {}; 
    for (var attr in obj) if (obj.hasOwnProperty(attr)) { 
     copy[attr] = obj[attr]; 
    } 
    return copy; 
} 

のみコピー属性の値(Object.update()がするよう)、とのようなオブジェクトに失敗しました210

質問

var mycopy = copy_obj(myobj); 
mycopy.fullname === 'fname lname' // true 
mycopy.fullname = 'Anton' 
mycopy.fullname === 'Anton' // oops! 

中:私は記述子を設定/取得するgetOwnPropertyNames /記述子を使用する必要があることを考え出しましたが、何かがちょうど平野であれば、私が決定する任意の簡単な方法を発見していません直接コピーすることができます値 - if文の中に何が起こっ:

function copy_obj2(obj) { 
    var mycopy = {}; 
    Object.getOwnPropertyNames(obj).forEach(function (prop) { 
     var descriptor = Object.getOwnPropertyDescriptor(obj, prop); 
     if (/* descriptor is a plain value */) { 
      mycopy[prop] = obj[prop]; 
     } else { 
      Object.defineProperty(mycopy, prop, descriptor); 
     } 
    }); 
    return mycopy; 
} 

(私はない配列または他の基本的なタイプ、オブジェクトのような値をコピー中にのみ興味が)。

+1

なぜあなたはどのような種類の記述子を気にしますか? 'Object.defineProperty'を使ってデータプロパティーを作成することもできます。 – Bergi

+0

ヒント: "普通の"記述子には '書き込み可能'と '値'フィールドがあり、 'get'や' set'はありません。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors#Description – Bergi

+0

データ記述子/プロパティーは、単純な値よりもはるかにオーバーヘッドではありませんか? – thebjorn

答えて

2

ディスクリプタの種類について心配する必要はありません。それがデータ型記述子であろうとアクセサ型の記述子であろうと、それをそのまま使用してターゲットオブジェクトにプロパティを作成することができます。

function copy_obj2(obj) { 
    var mycopy = {}; 
    Object.getOwnPropertyNames(obj).forEach(function (prop) { 
     var descriptor = Object.getOwnPropertyDescriptor(obj, prop); 
     Object.defineProperty(mycopy, prop, descriptor); 
    }); 
    return mycopy; 
} 

しかし、あなたはまたdefinePropertiesで、getOwnPropertyDescriptorsを使用することができます。

function copy_obj2(obj) { 
    return Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj)); 
} 

あなたもクローンで試作品を含めたい場合は、:

function copy_obj2(obj) { 
    return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); 
} 

しかし、getOwnPropertyDescriptorsではありませんIEで利用可能です。ポリフィルは、hereと示唆されています。

+0

'getOwnPropertyDescriptors'はChrome/FFでもかなり最近ですので、おそらくpolyfillを追加しなくても使用することはできません。 – thebjorn

関連する問題