Jika saya mengkloning sebuah array, saya menggunakan cloneArr = arr.slice()
Saya ingin tahu cara mengkloning objek di nodejs.
Jawaban:
Untuk utilitas dan kelas di mana tidak perlu memeras setiap penurunan kinerja, saya sering menipu dan hanya menggunakan JSON untuk melakukan salinan dalam:
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
Ini bukan satu-satunya jawaban atau jawaban yang paling elegan; semua jawaban lain harus dipertimbangkan untuk mengatasi kemacetan produksi. Namun, ini adalah solusi cepat dan kotor, cukup efektif, dan berguna dalam banyak situasi di mana saya akan mengkloning hash properti sederhana.
newObj = obj.clone(args...);
Object.assign belum disebutkan dalam salah satu jawaban di atas.
let cloned = Object.assign({}, source);
Jika Anda menggunakan ES6, Anda dapat menggunakan operator penyebaran:
let cloned = { ... source };
Referensi: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
let a = {x:1}; let b = Object.assign({}, a); a.x = 2; a.y = 1; console.log(a, b);
Ada beberapa modul Node di luar sana jika tidak ingin "menggulung milik Anda sendiri". Yang ini terlihat bagus: https://www.npmjs.com/package/clone
Sepertinya itu menangani semua jenis hal, termasuk referensi melingkar. Dari halaman github :
master klon mengkloning objek, array, objek Tanggal, dan objek RegEx. Semuanya dikloning secara rekursif, sehingga Anda bisa mengkloning tanggal dalam array di objek, misalnya. [...] Referensi melingkar? Ya!
Sulit untuk melakukan operasi kloning yang umum tetapi berguna karena apa yang harus dikloning secara rekursif dan apa yang harus disalin tergantung pada bagaimana objek tertentu seharusnya bekerja.
Sesuatu yang mungkin berguna adalah
function clone(x)
{
if (x === null || x === undefined)
return x;
if (typeof x.clone === "function")
return x.clone();
if (x.constructor == Array)
{
var r = [];
for (var i=0,n=x.length; i<n; i++)
r.push(clone(x[i]));
return r;
}
return x;
}
Dalam kode ini logikanya adalah
nullatau undefinedhanya mengembalikan yang sama (kasus khusus diperlukan karena ini adalah kesalahan untuk mencoba melihat apakah ada clonemetode)clone metode? lalu gunakan ituFungsi klon ini memungkinkan penerapan metode klon khusus dengan mudah ... misalnya
function Point(x, y)
{
this.x = x;
this.y = y;
...
}
Point.prototype.clone = function()
{
return new Point(this.x, this.y);
};
function Polygon(points, style)
{
this.points = points;
this.style = style;
...
}
Polygon.prototype.clone = function()
{
return new Polygon(clone(this.points),
this.style);
};
Ketika di objek Anda tahu bahwa operasi kloning yang benar untuk larik tertentu hanyalah salinan dangkal maka Anda dapat memanggil values.slice() bukan clone(values).
Misalnya dalam kode di atas, saya secara eksplisit mengharuskan kloning objek poligon akan mengkloning poin, tetapi akan menggunakan objek gaya yang sama. Jika saya ingin mengkloning objek gaya juga, maka saya bisa langsung saja clone(this.style).
.clonemetode itu sendiri. Ini adalah cara terbaik untuk menangani objek kloning.
if (x.clone)harusif (typeof x.clone === 'function')
Tidak ada metode asli untuk mengkloning objek. Mengimplementasikan _.clonegaris bawah yang merupakan klon dangkal.
_.clone = function(obj) {
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
Itu baik mengirisnya atau memanjangkannya.
Ini dia _.extend
// extend the obj (first parameter)
_.extend = function(obj) {
// for each other parameter
each(slice.call(arguments, 1), function(source) {
// loop through all properties of the other objects
for (var prop in source) {
// if the property is not undefined then add it to the object.
if (source[prop] !== void 0) obj[prop] = source[prop];
}
});
// return the object (first parameter)
return obj;
};
Perluas hanya dengan mengulang semua item dan membuat objek baru dengan item di dalamnya.
Anda dapat meluncurkan penerapan naif Anda sendiri jika mau
function clone(o) {
var ret = {};
Object.keys(o).forEach(function (val) {
ret[val] = o[val];
});
return ret;
}
Ada alasan bagus untuk menghindari kloning yang dalam karena closure tidak bisa dikloning.
Saya pribadi telah mengajukan pertanyaan tentang deep cloning objects beforedan kesimpulan yang saya dapatkan adalah Anda tidak melakukannya.
Rekomendasi saya adalah gunakan underscoredan _.clonemetode itu untuk klon dangkal
Untuk salinan yang dangkal, saya suka menggunakan pola pengurangan (biasanya dalam modul atau semacamnya), seperti:
var newObject = Object.keys(original).reduce(function (obj, item) {
obj[item] = original[item];
return obj;
},{});
Berikut adalah jsperf untuk beberapa opsi: http://jsperf.com/shallow-copying
Pertanyaan lama, tetapi ada jawaban yang lebih elegan dari yang telah disarankan sejauh ini; gunakan utils._extend bawaan:
var extend = require("util")._extend;
var varToCopy = { test: 12345, nested: { val: 6789 } };
var copiedObject = extend({}, varToCopy);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 } }
Perhatikan penggunaan parameter pertama dengan objek kosong {} - ini memberitahu perluasan bahwa objek yang disalin perlu disalin ke objek baru. Jika Anda menggunakan objek yang ada sebagai parameter pertama, maka parameter kedua (dan semua parameter berikutnya) akan disalin-penggabungan-dalam di atas variabel parameter pertama.
Menggunakan variabel contoh di atas, Anda juga dapat melakukan ini:
var anotherMergeVar = { foo: "bar" };
extend(copiedObject, { anotherParam: 'value' }, anotherMergeVar);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 }, anotherParam: 'value', foo: 'bar' }
Utilitas yang sangat berguna, terutama di mana saya biasa memperluas AngularJS dan jQuery.
Semoga ini bisa membantu orang lain; penimpaan referensi objek adalah kesengsaraan, dan ini menyelesaikannya setiap saat!
Bergantung pada apa yang ingin Anda lakukan dengan objek kloning Anda, Anda dapat memanfaatkan mekanisme pewarisan prototipe javascript dan mencapai objek yang dikloning melalui:
var clonedObject = Object.create(originalObject);
Ingatlah bahwa ini bukan klon lengkap - baik atau buruk.
Hal yang baik tentang itu adalah Anda sebenarnya belum menduplikasi objek sehingga jejak memori akan rendah.
Beberapa hal rumit yang perlu diingat tentang metode ini adalah bahwa iterasi properti yang ditentukan dalam rantai prototipe terkadang bekerja sedikit berbeda dan fakta bahwa setiap perubahan pada objek asli akan memengaruhi objek kloning juga kecuali properti itu telah disetel pada dirinya sendiri juga. .
var a = {foo: "bar"}, b = Object.create(a); a.foo = "broken"; console.log(b.foo); // "broken";
b.foo = "working"; console.log(a.foo); // still "broken";Orang tentu harus menyadari bahwa perubahan pada objek asli akan tercermin dalam "klon" dan bahwa perubahan dalam "klon" tidak akan tercermin dalam objek asli - tetapi saya tidak akan menyebutnya berbahaya - itu semua tergantung pada apa yang ingin Anda lakukan dengan klon Anda
Saya menerapkan salinan dalam lengkap. Saya percaya itu adalah pilihan terbaik untuk metode klon generik, tetapi tidak menangani referensi siklis.
parent = {'prop_chain':3}
obj = Object.create(parent)
obj.a=0; obj.b=1; obj.c=2;
obj2 = copy(obj)
console.log(obj, obj.prop_chain)
// '{'a':0, 'b':1, 'c':2} 3
console.log(obj2, obj2.prop_chain)
// '{'a':0, 'b':1, 'c':2} 3
parent.prop_chain=4
obj2.a = 15
console.log(obj, obj.prop_chain)
// '{'a':0, 'b':1, 'c':2} 4
console.log(obj2, obj2.prop_chain)
// '{'a':15, 'b':1, 'c':2} 4
Kode ini menyalin objek dengan prototipe mereka, itu juga menyalin fungsi (mungkin berguna untuk seseorang).
function copy(obj) {
// (F.prototype will hold the object prototype chain)
function F() {}
var newObj;
if(typeof obj.clone === 'function')
return obj.clone()
// To copy something that is not an object, just return it:
if(typeof obj !== 'object' && typeof obj !== 'function' || obj == null)
return obj;
if(typeof obj === 'object') {
// Copy the prototype:
newObj = {}
var proto = Object.getPrototypeOf(obj)
Object.setPrototypeOf(newObj, proto)
} else {
// If the object is a function the function evaluate it:
var aux
newObj = eval('aux='+obj.toString())
// And copy the prototype:
newObj.prototype = obj.prototype
}
// Copy the object normal properties with a deep copy:
for(var i in obj) {
if(obj.hasOwnProperty(i)) {
if(typeof obj[i] !== 'object')
newObj[i] = obj[i]
else
newObj[i] = copy(obj[i])
}
}
return newObj;
}
Dengan salinan ini saya tidak dapat menemukan perbedaan antara yang asli dan yang disalin kecuali jika yang asli menggunakan penutupan pada konstruksinya, jadi saya pikir ini adalah implementasi yang baik.
Saya harap ini membantu
untuk array, seseorang dapat menggunakan
var arr = [1,2,3];
var arr_2 = arr ;
print ( arr_2 );
arr = arr.slice (0);
print ( arr );
arr[1]=9999;
print ( arr_2 );
Objek dan Array dalam JavaScript menggunakan panggilan dengan referensi, jika Anda memperbarui nilai yang disalin itu mungkin mencerminkan objek aslinya. Untuk mencegah hal ini, Anda dapat mengkloning objek secara mendalam, untuk mencegah referensi diteruskan, menggunakan perintah run method lodash library cloneDeep
npm instal lodash
const ld = require('lodash')
const objectToCopy = {name: "john", age: 24}
const clonedObject = ld.cloneDeep(objectToCopy)