別の配列またはオブジェクトから新しい配列またはオブジェクトを作成する最良の方法は何でしょうか。やってから
var oldvar = {x:1,y:2} //or [x,y]
var newvar = oldvar
それらをリンクしますが、新しい変数を複製または対処する最善の方法は何でしょうか?
別の配列またはオブジェクトから新しい配列またはオブジェクトを作成する最良の方法は何でしょうか。やってから
var oldvar = {x:1,y:2} //or [x,y]
var newvar = oldvar
それらをリンクしますが、新しい変数を複製または対処する最善の方法は何でしょうか?
JavaScript の数値は、仕様で「プリミティブ値型」と呼ばれるものです
数値 # Ⓣ<br> 倍精度 64 ビット バイナリ形式の IEEE 754 値に対応するプリミティブ値。
注 Number 値は Number 型のメンバーであり、数値を直接表現したものです。
したがって、あなたの場合、参照ではなく oldvarのコピーnewvar
になります。
JavaScript ではNumber
、 、Boolean
、undefined
、null
またはString
は値の型です。これら5つのいずれかを渡す場合、実際には参照ではなく値を渡しているため、それらを複製する必要はありません。
(オブジェクト) 以外のものを渡す場合、それらは参照型であるため、クローンを使用する必要があります。
JavaScript でオブジェクトを複製する場合、2 つの方法があります。
これは、1 レベルの深さでクローンを作成することを意味します。オブジェクト内のすべてのプロパティが列挙可能であると仮定すると (これは通常、プロパティ記述子を使用していない場合に当てはまります)、次のようなものを使用できます。
var a = {a:3,b:5};
var copy = {};
for(var prop in a){
copy[prop] = a[prop];
}
しかし、多くの場合、オブジェクトがプロトタイプから継承するすべてのプロパティではなく、オブジェクト自体のプロパティをコピーしたいので、次のことができます。
var copy = {};
for(var prop in a){
if(a.hasOwnProperty(prop)){//check that the cloned property belongs to _a_ itself
copy[prop] = a[prop];
}
}
これら 2 つのシャロー コピー プロパティは off のみでa
あることに注意してください。これらはプロトタイプの設定を処理せず、参照によってすべてのプロパティを複製します (プリミティブ値型自体であるプロパティを除く:))。
ディープ コピーとは、複数レベルの深さのオブジェクトのクローンを作成することを意味します。ディープコピーはそのように定義されているため(疑似コードで)、これは再帰を呼び出します
CopyObject(object)
If object is a primitive value type
return object
clone := Empty Object
For every member of object
Add CopyObject(member) as a property to clone
Return clone
クローンのオブジェクト プロパティにアルゴリズムを再帰的に適用しています。
これは、私があなたのために文書化したサンプル実装です。ES5 (Chrome) を想定していますが、他のブラウザーや古いブラウザーにも簡単に適応させることができます。治療Date
やRegex
特別なケースのような、より多くのことを行います。また、オブジェクト内の循環参照を処理できるように、処理済みのプロパティの辞書も保持します。これは学習用であり、本番用ではありません :) ご不明な点がございましたら、お気軽にお問い合わせください。
var clone = function (a) {
var passedRefs = []; // Keep track of references you passed to avoid cycles
var passedRefCreated = [];
function clone2(a1) { // Inner function to handle the actual cloning
var obj;
if (typeof a1 !== "object" || a1 === null) { // Handle value type
return a1;
}
var locInpPassed = passedRefs.indexOf(a1); // Detect circular reference
if (locInpPassed !== -1) {
return passedRefCreated[locInpPassed];
}
passedRefs.push(a1); // Add the object to the references to avoid circular references later
if (a1 instanceof Date) { // Handle date and RegExp for special cases
obj = new Date(a1.getTime());
} else if (a1 instanceof RegExp) {
obj = new RegExp(a1);
}else if (Array.isArray(a1)){// handle arrays in order for Array.isArray to work. Thanks FizzyTea for catching this.
obj = [];
} else { // Create a new object with the prototype of the one we're cloning to support prototypical inheritance. Prototypes are _shared_
obj = Object.create(Object.getPrototypeOf(a1));
}
passedRefCreated[passedRefs.indexOf(a1)] = obj; // Add to the references created dict
Object.getOwnPropertyNames(a1).forEach(function (prop) { // Go through all the property, even the ones that are not enumerable
obj[prop] = clone2(a1[prop]); // Call the algorithm recursively, just like in the pseudo code above
});
return obj;
}
return clone2(a); // Call the inner function that has access to the dictionary
}
(たとえば、for... in
ループを使用してプロパティを反復処理できます)。