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
-~----------~----~----~----~------~----~------~--~---

Reply via email to