I really need to have a separate copy of an object - they are small and it needn't to have heavy computations and consume a lot of memory
On 8 окт, 17:16, "T.J. Crowder" <[EMAIL PROTECTED]> wrote: > > True use-cases for deep-cloning are actually pretty rare. > > I'll second that. > > > I'm not sure what you are attempting to do here, but there's most > > certainly a better way of doing it without needing deep-cloning. > > I think I'd go with "probably". :-) > > But yeah, buda, you might want to step back and look at what you're > really trying to accomplish. Maybe you need deep cloning, but in > (let's see...) 17 years as a professional software engineer on a > variety of platforms, I've only really needed to do it a couple of > times... > -- > T.J. Crowder > tj / crowder software / com > > On Oct 8, 2:51 pm, Tobie Langel <[EMAIL PROTECTED]> wrote: > > > > > True use-cases for deep-cloning are actually pretty rare. > > > When bumping into such an issue, it's usually a good idea to look for > > a better coding pattern rather than to add complexity, augment memory > > consumption and worsen the performance by bringing out the big guns. > > > I'm not sure what you are attempting to do here, but there's most > > certainly a better way of doing it without needing deep-cloning. > > > Just my two-cents. > > > Best, > > > Tobie > > > On Oct 8, 2:05 pm, "T.J. Crowder" <[EMAIL PROTECTED]> wrote: > > > > Hi, > > > > Object.clone is documented as being a shallow > > > copy:http://www.prototypejs.org/api/object/clone > > > > "Deep" cloning is more complicated than it seems at first. A naive > > > version would be along these lines: > > > > Object.extend(Object, { > > > deepClone: function(source) { > > > var result; > > > var property; > > > var val; > > > > result = {}; > > > for (property in source) > > > { > > > val = source[property]; > > > if (typeof val == "object" && !Object.isFunction(val)) > > > { > > > result[property] = Object.deepClone(val); > > > } > > > else > > > { > > > result[property] = val; > > > } > > > } > > > return result; > > > } > > > > }); > > > > Caveat: I'm not at all sure "typeof val == 'object' && ! > > > Object.isFunction(val)" is an adequate check for whether we should > > > clone the property. > > > > BUT, note that that does NOT correctly handle the full object graph. > > > Consider: > > > > var a, thing; > > > > thing = { name: 'original' }; > > > a = {}; > > > a.first = thing; > > > a.second = thing; > > > > a.first.name = 'changed'; > > > > At this point, a.first.name and a.second.name both have the value > > > 'changed'. But if you used the deepClone above before changing it: > > > > var a, thing; > > > > thing = { name: 'original' }; > > > a = {}; > > > a.first = thing; > > > a.second = thing; > > > > a = Object.deepClone(a); // <= ADDED THIS > > > > a.first.name = 'changed'; > > > > ...then a.first.name is 'changed' but a.second.name is 'original'. > > > The "deep" clone is not a correct clone, because it didn't recognise > > > that two properties referenced the same instance. > > > > It gets even worse if the object refers to itself, as the deepClone > > > function above would infinitely recurse. > > > > Handling the full graph correctly would require that during a > > > particular cloning operation, you maintained a bag of cloned objects > > > keyed by *identity* (===) and reused the clones if you'd already > > > cloned them in the past. Something like this: > > > > (On pastie:http://pastie.org/287641) > > > * * * * * * > > > /** > > > * A very quick-and-dirty bag for having values associated with * a > > > key that's compared by > > > * identity (===) > > > */ > > > var SlowIdentityBag = Class.create({ > > > > /** > > > * Create an empty bag. > > > */ > > > initialize: function() { > > > this.items = []; > > > }, > > > > /** > > > * Get an entry from the bag for the given key. > > > * > > > * @param key The key to search for > > > * @return the associated value, or undefined if not found > > > */ > > > get: function(key) { > > > var index; > > > var entry; > > > > for (index = this.items.length - 1; index >= 0; --index) > > > { > > > entry = this.items[index]; > > > if (entry.key === key) > > > { > > > return entry.val; > > > } > > > } > > > > return undefined; > > > }, > > > > /** > > > * Put the given value in the bag with the given key. > > > * > > > * @param key Take a wild guess > > > * @param val See above > > > */ > > > put: function(key, val) { > > > > this.items.push({ key: key, val: val}); > > > } > > > > }); > > > > Object.extend(Object, { > > > /** > > > * Deeply clone an object, preserving the object graph by only > > > cloning each object once and > > > * reusing it if necessary. > > > * > > > * @param source The source object to clone > > > * @param clonesByIdentity Usually omitted; if given, a > > > SlowIdentityBag containing > > > * previously-cloned objects to reuse > > > keyed by the originals. > > > * MUST NOT contain 'source'. > > > */ > > > deepClone: function(source, clonesByIdentity) { > > > var result; > > > var property; > > > var val; > > > > // A blank result object > > > result = {}; > > > > // Usually we create this unless we're calling ourselves > > > if (!clonesByIdentity) > > > { > > > clonesByIdentity = new SlowIdentityBag(); > > > } > > > > // The source may be self-referential, so remember the > > > instance > > > // we're cloning it to at the outset > > > clonesByIdentity.put(source, result); > > > > // Process the properties > > > for (property in source) > > > { > > > val = source[property]; > > > if (typeof val == "object" && !Object.isFunction(val)) > > > { > > > // Something we should clone, if we haven't already. > > > // (That check is probably not adequate.) > > > // Grab it or clone it. Note that deepClone will > > > // add it to the bag. > > > val = clonesByIdentity.get(val) || > > > Object.deepClone(val, clonesByIdentity); > > > } > > > result[property] = val; > > > } > > > return result; > > > }}); > > > > * * * * * * > > > > Caveats on that: > > > > 1. This is very much off-the-cuff. > > > 2. Same caveat as earlier about the check for whether to clone the > > > object. > > > 3. I can't imagine it's all that fast. Offhand I couldn't think of a > > > faster way to do the SlowIdentityBag; anyone have a l33t idea there? > > > > FWIW, > > > -- > > > T.J. Crowder > > > tj / crowder software / com > > > > On Oct 8, 4:18 am, buda <[EMAIL PROTECTED]> wrote: > > > > > I have an object > > > > > var obj = { > > > > info: { > > > > section:{ > > > > CountryCities:{ > > > > filter: { > > > > CountryID: 'MyCountry' > > > > } > > > > } > > > > } > > > > } > > > > > } > > > > > var arg = Object.clone(obj); > > > > arg.info.section.CountryCities.CountryID = '100'; > > > > > or > > > > > var arg = Object.extend({}, obj); > > > > arg.info.section.CountryCities.CountryID = '100'; > > > > > do the same => > > > > arg.info.section.CountryCities.CountryID = > > > > obj.info.section.CountryCities.CountryID = 100 > > > > > but I need an independent copy of an obj in arg!!!!! > > > > > How could I do it?- Скрыть цитируемый текст - > > - Показать цитируемый текст - --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~----------~----~----~----~------~----~------~--~---