Newsgroups: comp.lang.javascript
From: "Richard Cornford" <Rich...@litotes.demon.co.uk>
Date: Sun, 30 Mar 2008 18:35:59 +0100
Local: Sun, Mar 30 2008 1:35 pm
Subject: Re: Prototypal inheritance and mutable objects
Nick Fletcher wrote: As javascript is a language that uses prototypal inheritance it could be > I've recently been working on a fairly large JavaScript project > using prototypal inheritance. argued that if you use the language you are using prototypal inheritance, and so that saying as much would be redundant. > I've been using this commonly seen clone (a.k.a. object) function Which is an example of the process that clearly expresses what is being > for implementing the inheritance hierarchies: > function clone(o) { done, but is not particularly efficient as it creates a new - F - function each time it is executed, but all of those - F - functions are essentially identical. If this is to be done often then a more efficient approach would be to only create a single - F - function and put it where it could not be modified by external code. I.E.:- var clone = (function(){ })(); You have not said why you are using your - clone - function (why you considered its use appropriate in your context and superior to the may other approaches possible). > The problem I've come across is that mutable objects in my Yes, that is what happens here. Indeed it is one of the aspects of this > "Prototype Object" get shared for all inheriting instances > of the object. strategy that make it useful as it avoids the need to explicitly assign references to commonly shared object. > For But this example is far too simplistic to justify the use of a - clone - > example, a rudimentary collections API: > /** > /** > /** > Any cloned objects that I create will all share the same 'items' > var list = clone(List); > list.add("one"); method as a simple constructor/prototype definition would get the job done with a negligible difference in the complexity of the code used (and could be argued to be clearer as it would be the more natural approach when using javascript). I.E.:- function Collection(){ } Collection.prototype.add = function(){ this.items[this.items.length] = item; }; Collection.prototype.remove = function(){ var count = 0; for (var i = 0, len = this.items.length; i < len; ++i) { if (item === this.items[i]) { this.items.splice(i, 1); --i; --len; } } }; function List(){ this.items = []; } List.prototype = new Collection(); //or:- List.prototype = clone(Collection.prototype); List.prototype.insert = function (item, index) { this.items.splice(index, 0, item); }; List.prototype.get = function (index) { return this.items[index]; }; function Set(){ this.items = []; } Set.prototype = new Collection(); //or:- Set.prototype = clone(Collection.prototype); Set.prototype.add = function (item) { for (var i = 0, len = this.items.length; i < len; i++) { if (item === this.items[i]) { return; } } this.items[this.items.length] = item; }; var list = new List(); var set = new Set(); list.add("one"); > One solution would be for all cloned objects to explicitly So you have an approach that does not employ a constructor function and > set their own copies of the mutable objects, which can be a > bit of a bother (especially if there are a lot). > My current working solution is to add a 'create' method to > var Collection = { > return collection; > // add and remove > Now I can create as many instances as I want and they will all have > var list = List.create(); > list.add("one"); so does not get the set-up on instanceiation that comes with the - new - operator and constructor functions, so you have added another function that is used in place of the constructor. That seems to be doing a lot of work to get back to what the language would have given you form day one. > There's still the problem of having to attach all super mutable A good approach to what exactly? I use this style of cloning when I want > objects to an inheriting object if you want to add another mutable > property: > Sub = clone(Collection); > return collection; > This could be quite annoying if you have a lot of mutable objects that > Sub = clone(Collection); > return sub; > My questions are: Is this a good approach? multiple object instances that share some sort of runtime determined set-up or configuration so that they do not need to go through that process again when each new instance is created, but then the object being cloned is either never used as an actual instance or the cloning process has to mask instance specific aspects of the original (requiring a more elaborate cloning process). I do not use this approach for inheritance relationships that could be statically defined in the source code. > What are my alternatives? The alternatives depend on the 'why', but there will be hundreds (and most of them, but probably not all of them, will be worse). > Am I completely out of my mind? Probably not (and certainly not for asking). However, keep a few facts in mind; client-side javascript is vary rarely so complex that it needs deep inheritance hierarchies, the language has a natural inheritance mechanism that should not be deviated from until doing so has some manifest advantage (that can be clearly stated), and that any single 'formal inheritance strategy' applied across the board is likely to act as a straightjacket and preclude possibilities that could be useful and/or interesting. Richard. You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
| ||||||||||||||