Jika saya mengkloning sebuah array, saya menggunakan cloneArr = arr.slice()
Saya ingin tahu cara mengkloning objek di nodejs.
javascript
node.js
guilin 桂林
sumber
sumber
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
sumber
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 :
sumber
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
null
atauundefined
hanya mengembalikan yang sama (kasus khusus diperlukan karena ini adalah kesalahan untuk mencoba melihat apakah adaclone
metode)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()
bukanclone(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)
.sumber
.clone
metode 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
_.clone
garis 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 before
dan kesimpulan yang saya dapatkan adalah Anda tidak melakukannya.Rekomendasi saya adalah gunakan
underscore
dan_.clone
metode itu untuk klon dangkalsumber
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
sumber
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!
sumber
Anda juga bisa menggunakan lodash . Ini memiliki metode clone dan cloneDeep .
var _= require('lodash'); var objects = [{ 'a': 1 }, { 'b': 2 }]; var shallow = _.clone(objects); console.log(shallow[0] === objects[0]); // => true var deep = _.cloneDeep(objects); console.log(deep[0] === objects[0]);
sumber
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. .
sumber
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 AndaSaya menerapkan salinan dalam lengkap. Saya percaya itu adalah pilihan terbaik untuk metode klon generik, tetapi tidak menangani referensi siklis.
Contoh penggunaan:
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 itu sendiri:
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
sumber
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 );
sumber
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
const ld = require('lodash') const objectToCopy = {name: "john", age: 24} const clonedObject = ld.cloneDeep(objectToCopy)
sumber