यदि मैं एक सरणी क्लोन करता हूं, तो मैं उपयोग करता हूं cloneArr = arr.slice()
मैं जानना चाहता हूं कि नोडज में किसी ऑब्जेक्ट को कैसे क्लोन किया जाए।
जवाबों:
उपयोगिताओं और कक्षाओं के लिए जहां प्रदर्शन की हर बूंद को निचोड़ने की आवश्यकता नहीं होती है, मैं अक्सर धोखा देता हूं और एक गहन प्रदर्शन करने के लिए सिर्फ JSON का उपयोग करता हूं:
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
यह एकमात्र उत्तर या सबसे सुरुचिपूर्ण उत्तर नहीं है; उत्पादन के अड़चनों के लिए अन्य सभी उत्तरों पर विचार किया जाना चाहिए। हालांकि, यह एक त्वरित और गंदे समाधान है, जो ज्यादातर स्थितियों में काफी प्रभावी और उपयोगी है, जहां मैं गुणों का एक साधारण हैश क्लोन कर सकता हूं।
newObj = obj.clone(args...);
उपर्युक्त किसी भी उत्तर में Object.assign का उल्लेख नहीं किया गया है।
let cloned = Object.assign({}, source);
यदि आप ES6 पर हैं, तो आप प्रसार ऑपरेटर का उपयोग कर सकते हैं:
let cloned = { ... source };
संदर्भ: 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);
अगर वहाँ "अपने खुद के रोल" नहीं करना चाहते हैं तो कुछ नोड मॉड्यूल हैं। यह एक अच्छा लग रहा है: https://www.npmjs.com/package/clone
ऐसा लगता है कि यह परिपत्र संदर्भ सहित सभी प्रकार के सामान को संभालता है। से GitHub पेज:
क्लोन मास्टर्स ऑब्जेक्ट्स, सरणियों, दिनांक ऑब्जेक्ट्स और RegEx ऑब्जेक्ट्स का क्लोनिंग करते हैं। सब कुछ पुनरावर्ती रूप से क्लोन किया जाता है, ताकि आप ऑब्जेक्ट में सरणियों में दिनांक क्लोन कर सकें, उदाहरण के लिए। [...] परिपत्र संदर्भ? हां!
यह एक सामान्य लेकिन उपयोगी क्लोन ऑपरेशन करना कठिन है क्योंकि जो पुनरावर्ती रूप से क्लोन किया जाना चाहिए और जो कॉपी किया जाना चाहिए वह इस बात पर निर्भर करता है कि विशिष्ट वस्तु को कैसे काम करना चाहिए।
जो कुछ उपयोगी हो सकता है वह है
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;
}
इस कोड में तर्क है
null
या undefined
बस लौट ही (विशेष मामले की जरूरत है, क्योंकि यह एक त्रुटि है, तो एक को देखने के लिए प्रयास करने के लिए clone
विधि मौजूद है)clone
विधि है? तो उस का उपयोग करेंइस क्लोन फ़ंक्शन को कस्टम क्लोन तरीकों को आसानी से लागू करने की अनुमति देनी चाहिए ... उदाहरण के लिए
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);
};
जब वस्तु में आप जानते हैं कि एक विशिष्ट सरणी के लिए एक सही क्लोनिंग ऑपरेशन सिर्फ एक उथली प्रतिलिपि है तो आप values.slice()
इसके बजाय कॉल कर सकते हैं clone(values)
।
उदाहरण के लिए उपरोक्त कोड में मुझे स्पष्ट रूप से आवश्यकता है कि बहुभुज वस्तु का एक क्लोनिंग अंक को क्लोन करेगा, लेकिन उसी शैली की वस्तु को साझा करेगा। अगर मैं इसके बजाय स्टाइल ऑब्जेक्ट को क्लोन करना चाहता हूं तो मैं बस पास कर सकता हूं clone(this.style)
।
.clone
स्वयं विधि लागू करने की आवश्यकता है । क्लोनिंग ऑब्जेक्ट से निपटने का यह सबसे अच्छा तरीका है।
if (x.clone)
होना चाहिएif (typeof x.clone === 'function')
क्लोनिंग ऑब्जेक्ट्स के लिए कोई मूल विधि नहीं है। अंडरस्कोर लागू करता है_.clone
करता है जो एक उथले क्लोन है।
_.clone = function(obj) {
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
यह या तो इसे काट देता है या इसका विस्तार करता है।
यहां बताया गया है _.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;
};
बस सभी आइटम्स के माध्यम से पुनरावृत्त करें और इसमें आइटमों के साथ एक नई वस्तु बनाएं।
यदि आप चाहते हैं तो आप अपने स्वयं के अनुभवहीन कार्यान्वयन को रोल आउट कर सकते हैं
function clone(o) {
var ret = {};
Object.keys(o).forEach(function (val) {
ret[val] = o[val];
});
return ret;
}
गहरी क्लोनिंग से बचने के अच्छे कारण हैं क्योंकि क्लोजर को क्लोन नहीं किया जा सकता है।
मैंने व्यक्तिगत रूप से एक प्रश्न पूछा है deep cloning objects before
और मैं जिस निष्कर्ष पर पहुंचा हूं वह यह है कि आप ऐसा नहीं करते हैं।
मेरी सिफारिश का उपयोग है underscore
और यह _.clone
उथले क्लोनों के लिए विधि है
उथली प्रतिलिपि के लिए, मैं कम पैटर्न (आमतौर पर एक मॉड्यूल या इस तरह) का उपयोग करना पसंद करता हूं, जैसे:
var newObject = Object.keys(original).reduce(function (obj, item) {
obj[item] = original[item];
return obj;
},{});
यहाँ विकल्पों के एक जोड़े के लिए एक jsperf है: http://jsperf.com/shallow-copying
पुराना प्रश्न, लेकिन अब तक जो सुझाव दिया गया है, उससे कहीं अधिक सुरुचिपूर्ण उत्तर है; अंतर्निहित बर्तनों का उपयोग करें। कस्टम:
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 } }
किसी खाली वस्तु {} के साथ पहले पैरामीटर के उपयोग पर ध्यान दें - यह बताता है कि प्रतिलिपि की गई वस्तु (ओं) को एक नई वस्तु में कॉपी करने की आवश्यकता है। यदि आप पहले पैरामीटर के रूप में किसी मौजूदा ऑब्जेक्ट का उपयोग करते हैं, तो दूसरा (और बाद के सभी) पैरामीटर पहले पैरामीटर चर पर गहरे-मर्ज-कॉपी होंगे।
उपरोक्त उदाहरण चर का उपयोग करके, आप यह भी कर सकते हैं:
var anotherMergeVar = { foo: "bar" };
extend(copiedObject, { anotherParam: 'value' }, anotherMergeVar);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 }, anotherParam: 'value', foo: 'bar' }
बहुत उपयोगी उपयोगिता, विशेष रूप से जहां मुझे AngularJS और jQuery में विस्तार करने के लिए उपयोग किया जाता है।
मनाइए कि यह किसी और के लिए सहायक हो; ऑब्जेक्ट संदर्भ ओवरराइट एक दुख है, और यह हर बार इसे हल करता है!
आप चाहें तो लॉश का भी इस्तेमाल कर सकते हैं । इसमें एक क्लोन और क्लोनडिप विधियां हैं।
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]);
आप अपने क्लोन किए गए ऑब्जेक्ट के साथ क्या करना चाहते हैं, इस पर निर्भर करता है कि आप जावास्क्रिप्ट की प्रोटोटाइप विरासत प्रणाली का उपयोग कर सकते हैं और इसके माध्यम से कुछ क्लोन वस्तु प्राप्त कर सकते हैं:
var clonedObject = Object.create(originalObject);
बस याद रखें कि यह एक पूर्ण क्लोन नहीं है - बेहतर या बदतर के लिए।
इसके बारे में एक अच्छी बात यह है कि आपने वास्तव में ऑब्जेक्ट को डुप्लिकेट नहीं किया है इसलिए मेमोरी फ़ुटप्रिंट कम होगा।
इस पद्धति के बारे में याद रखने वाली कुछ कठिन बातें यह है कि प्रोटोटाइप श्रृंखला में परिभाषित गुणों की पुनरावृत्ति कभी-कभी कुछ अलग काम करती है और यह तथ्य कि मूल वस्तु में कोई भी परिवर्तन क्लोन की गई वस्तु को प्रभावित करेगा, जब तक कि वह संपत्ति स्वयं भी निर्धारित न हो जाए। ।
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";
निश्चित रूप से इस बात से अवगत होना चाहिए कि मूल वस्तु में परिवर्तन "क्लोन" में परिलक्षित होगा और "क्लोन" में होने वाले परिवर्तन मूल वस्तु में परिलक्षित नहीं होंगे - लेकिन मैं इसे खतरनाक नहीं कहूंगा। - यह सब इस बात पर निर्भर करता है कि आप अपने क्लोन के साथ क्या करना चाहते हैं
मैंने पूरी गहरी कॉपी लागू की। मेरा मानना है कि जेनेरिक क्लोन विधि के लिए इसकी सबसे अच्छी पसंद है, लेकिन यह चक्रीय संदर्भों को नहीं संभालता है।
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
यह कोड वस्तुओं को उनके प्रोटोटाइप के साथ कॉपी करता है, यह फ़ंक्शन को भी कॉपी करता है (किसी के लिए उपयोगी हो सकता है)।
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;
}
इस प्रति के साथ मुझे मूल और कॉपी किए गए एक के बीच कोई अंतर नहीं मिल सकता है, सिवाय इसके कि अगर मूल इसके निर्माण पर बंद हुआ, तो मुझे लगता है कि यह एक अच्छा कार्यान्वयन है।
मुझे उम्मीद है यह मदद करेगा
यदि आप कॉपी किए गए मूल्य को अद्यतन करते हैं तो यह जावास्क्रिप्ट में ऑब्जेक्ट्स और ऐरे संदर्भ द्वारा कॉल का उपयोग करता है, यह मूल वस्तु पर प्रतिबिंबित हो सकता है। इसे रोकने के लिए, आप ऑब्जेक्ट को क्लोन कर सकते हैं, संदर्भ को रोकने के लिए, लॉश लाइब्रेरी क्लोनडिप विधि कमांड का उपयोग करके
npm इंस्टाल करें
const ld = require('lodash')
const objectToCopy = {name: "john", age: 24}
const clonedObject = ld.cloneDeep(objectToCopy)