"javascript clone object"のグーグルは、いくつかの本当に奇妙な結果をもたらします、それらのいくつかは絶望的に時代遅れであり、いくつかはあまりに複雑すぎます。
let clone = {...original};
これに問題はありますか?
"javascript clone object"のグーグルは、いくつかの本当に奇妙な結果をもたらします、それらのいくつかは絶望的に時代遅れであり、いくつかはあまりに複雑すぎます。
let clone = {...original};
これに問題はありますか?
回答:
これは浅いクローニングに適しています。オブジェクトの広がりは、ECMAScriptの2018の標準的な部分です。
ディープクローンを作成するには、別のソリューションが必要です。
const clone = {...original}
浅いクローンに
const newobj = {...original, prop: newOne}
オリジナルに別のプロップを不変に追加し、新しいオブジェクトとして保存します。
JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
は機能しません。存在する場合、functions
またはinfinity
値として存在 する場合は、単にnull
その場所に割り当てられるためです。値が単純な場合literals
とそうでない場合にのみ機能しますfunctions
。
編集:この回答が投稿されたとき{...obj}
、ほとんどのブラウザでは構文が利用できませんでした。今日では、IE 11をサポートする必要がない限り、問題なく使用できます。
Object.assignを使用します。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
ただし、これではディープクローンは作成されません。現在のところ、ディープクローニングのネイティブな方法はまだありません。
編集:@Mike 'Pomax' Kamermansがコメントで述べたように、以下を使用して単純なオブジェクト(つまり、プロトタイプ、関数、または循環参照なし)をディープクローンできます。 JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
は、適切なディープクローンが1つあります。ただし、プロトタイプ、関数、または循環参照が機能している瞬間、そのソリューションは機能しなくなります。
使用したメソッドがDateなどのデータ型を含むオブジェクトでうまく機能しない場合は、これを試してください
インポート _
import * as _ from 'lodash';
ディープクローンオブジェクト
myObjCopy = _.cloneDeep(myObj);
import _ from 'lodash';
十分です。しかし、「ホイールを再発明しないでください」という答えの+1。
json.parse(json.stringify(object))を使用したくない場合は、再帰的にキーと値のコピーを作成できます。
function copy(item){
let result = null;
if(!item) return result;
if(Array.isArray(item)){
result = [];
item.forEach(element=>{
result.push(copy(element));
});
}
else if(item instanceof Object && !(item instanceof Function)){
result = {};
for(let key in item){
if(key){
result[key] = copy(item[key]);
}
}
}
return result || item;
}
しかし、最善の方法は、自身のクローンを返すことができるクラスを作成することです
class MyClass{
data = null;
constructor(values){ this.data = values }
toString(){ console.log("MyClass: "+this.data.toString(;) }
remove(id){ this.data = data.filter(d=>d.id!==id) }
clone(){ return new MyClass(this.data) }
}
@marcelの回答に続いて、クローンされたオブジェクトで一部の関数がまだ見つからないことがわかりました。例えば
function MyObject() {
var methodAValue = null,
methodBValue = null
Object.defineProperty(this, "methodA", {
get: function() { return methodAValue; },
set: function(value) {
methodAValue = value || {};
},
enumerable: true
});
Object.defineProperty(this, "methodB", {
get: function() { return methodAValue; },
set: function(value) {
methodAValue = value || {};
}
});
}
MyObjectではmethodAを複製できましたが、methodBは除外されました。これは欠落しているために発生しました
enumerable: true
それはそれが現れなかったことを意味しました
for(let key in item)
代わりに私はに切り替えました
Object.getOwnPropertyNames(item).forEach((key) => {
....
});
列挙できないキーが含まれます。
また、プロトタイプ(proto)が複製されていないこともわかりました。そのため、私は結局使用しました
if (obj.__proto__) {
copy.__proto__ = Object.assign(Object.create(Object.getPrototypeOf(obj)), obj);
}
PS:これを行うための組み込み関数を見つけることができなかったことに不満を感じています。
こうすることもできます
let copiedData = JSON.parse(JSON.stringify(data));
We can do that with two way:
1- First create a new object and replicate the structure of the existing one by iterating
over its properties and copying them on the primitive level.
let user = {
name: "John",
age: 30
};
let clone = {}; // the new empty object
// let's copy all user properties into it
for (let key in user) {
clone[key] = user[key];
}
// now clone is a fully independant clone
clone.name = "Pete"; // changed the data in it
alert( user.name ); // still John in the original object
2- Second we can use the method Object.assign for that
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
// copies all properties from permissions1 and permissions2 into user
Object.assign(user, permissions1, permissions2);
-Another example
let user = {
name: "John",
age: 30
};
let clone = Object.assign({}, user);
It copies all properties of user into the empty object and returns it. Actually, the same as the loop, but shorter.
しかし、Object.assign()は深いクローンを作成しません
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
let clone = Object.assign({}, user);
alert( user.sizes === clone.sizes ); // true, same object
// user and clone share sizes
user.sizes.width++; // change a property from one place
alert(clone.sizes.width); // 51, see the result from the other one
これを修正するには、user [key]の各値を調べる複製ループを使用し、それがオブジェクトの場合は、その構造も複製する必要があります。これは「ディープクローニング」と呼ばれます。
上記のケースとより複雑なケースを処理するディープクローニングの標準アルゴリズムがあり、構造化クローニングアルゴリズムと呼ばれます。車輪の再発明をしないようにするために、我々は、JavaScriptライブラリからの作業の実装を使用することができますlodashメソッドが呼び出され_.cloneDeep(OBJ) 。
上記のすべてのメソッドは、nレベルにネストされているオブジェクトのディープクローニングを処理しません。私は他の人と比べてそのパフォーマンスをチェックしませんでしたが、それは短くてシンプルです。
以下の最初の例はObject.assign
、最初のレベルまでのクローンを使用したオブジェクトのクローン作成を示しています。
var person = {
name:'saksham',
age:22,
skills: {
lang:'javascript',
experience:5
}
}
newPerson = Object.assign({},person);
newPerson.skills.lang = 'angular';
console.log(newPerson.skills.lang); //logs Angular
以下のアプローチを使用して、ディープクローンオブジェクト
var person = {
name:'saksham',
age:22,
skills: {
lang:'javascript',
experience:5
}
}
anotherNewPerson = JSON.parse(JSON.stringify(person));
anotherNewPerson.skills.lang = 'angular';
console.log(person.skills.lang); //logs javascript
original = { a: [1,2,3] }
はclone.a
文字通りのクローンを提供しますoriginal.a
。いずれclone
かによるoriginal
変更または同じものを変更するため、いいえ、これは悪い=)