Javascriptでオブジェクトをコピーする必要がある場合のベストプラクティスです。
例えば:
オブジェクトがあります{ name: 'Dodo', method: function () { console.log(this.name) }}
;
私はそれのコピーを作成する必要があります:
var obj = { name: 'Dodo', method: function () { console.log(this.name) } };
// what is better?
var copyUnderscore = _(obj).clone();
var copySimple = obj;
より良い方法は何ですか?ありがとう!
__.clone
_は、割り当てとはまったく異なります。
__.clone
_は新しいオブジェクトを作成し、各値を元のオブジェクトから新しいオブジェクトにコピーします。
割り当ては、既存のオブジェクトを変数にポイントするだけです。
子犬がいたとします。彼をレックスと呼びましょう。
Rexについて誰かと話している場合、Rex、または「the Dog」と呼ぶことにします。どちらも問題の動物への言及です。割り当ては、ペットにさまざまなフレーズを使用することに似ています。
_rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
// Note the use of `===`, which checks for object identity.
// Assignment (as above) is the whole point of `===`
if (theDog === rex) {
alert("The Dog is the Same as Rex");
}
_
1つについて何かを変更すると、両方の参照についても変更されます。レックスを「修正」するとします。
_rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
rex.fix();
alert("The Dog is " + (theDog.fixed ? "" : "not ") + "fixed");
alert("Rex is " + (rex.fixed ? "" : "not ") + "fixed");
_
theDog
も修正されました。
レックスのクローンを作成したとします。 (議論のためにまだ修正されていないふりをしましょう)。
_rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
otherDog = _.clone(rex);
console.log(theDog);
console.log(rex);
console.log(otherDog);
var message = rex === theDog ? "Rex is the same as the dog" : "Rex and the dog are different";
message += "\n";
message += rex === otherDog ? "Rex is the same as the other dog" : "Rex is different from the other dog";
message += "\n";
message += rex.fixed ? "Rex is fixed" : "Rex is not fixed";
message += "\n";
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed";
alert(message);
otherDog.fix();
message = rex.fixed ? "Rex is fixed" : "Rex is not fixed";
message += "\n";
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed";
alert(message);
_
_<script src="http://underscorejs.org/underscore-min.js"></script>
_
rex
の各値はotherDog
にコピーされています。奇跡的に、「otherDog」は12週齢で生まれました。ただし、一方を修正すると他方は修正されません。
rex
とtheDog
は同じ犬なので、どちらも修正されていません。ただし、otherDog
isは修正されています。彼はクローンであり、同じ動物ではありません。
注意すべき点がいくつかあります。 __.clone
_は深くコピーしません。これは、複製されたオブジェクトの値であるオブジェクトまたは配列は、assignmentによって新しいオブジェクトにコピーされることを意味します(その意味については、最初のスニペットを参照してください)。
これは、rex
が母親を表すオブジェクトであるプロパティmother
を持っている場合、rex
とotherDog
の間で共有されることを意味します。 rex
の母親への変更は、otherDog
に伝播されます。これは実際の生活とそれほど違いはありません。生物学的な母親はまったく同じです。
[〜#〜] edit [〜#〜]
別の奇跡的なメモとして:固定犬のクローンを作成すると、別の固定犬が作成されます。これは、生物学的メタファーが壊れる場所です。
もう一度編集(2018年6月)
この質問の読者が興味を持つ可能性のある2つの追加のES6機能があります。
以下は__.clone
_(メンバーのコピー)と同じです。
_let x = {...rex};
_
次は、メンバーを既存のオブジェクトにコピーし、そのオブジェクトを返します。
let x = {}; let anotherReferenceToX = Object.assign(x, rex);
ボーナス!
lodashは実際にはに深いクローン操作がある であることに注意する価値があります。 function (x) { return JSON.parse(JSON.stringify(x)) }
を使用することもできます。しかし、それは循環参照で窒息し、lodashはそうではありません。