I've signed up in the hope that someone can finally provide an exposition of Javascript's prototype inheritance that actually works. The specific code I'm interested in, centres upon a library I wrote myself to handle such tasks as the generation of linked lists, binary trees, etc., and for which I defined the following constructor:
function ListLinks(objLink)
{
this.prev = null;
this.next = null;
this.content = objLink;
}
The idea is that the 'prev' and 'next' properties are links to other ListLinks objects, and the 'content' property is a link to the object containing the data being inserted into the list or tree.
Now, using references to the prototype object associated with the above ListLinks object, I successfully added some class methods, to perform tasks such as entry insertion, entry removal, list traversal, and tree traversal. These all work nicely.
Now, because I want to take advantage of this functionality in a new object type, I thought that the intelligent approach would be to inherit that functionality, including all the properties and methods, from the ListLinks object in the new object. The new object I called a RenderTree object, because I'm interested in generating a binary tree of graphical rendering data. The idea being that I can sort my rendering data on input into the tree by distance from the viewing camera, and use an in-order traversal of the tree to implement the Painter Algorithm. But that isn't my problem.
My problem is persuading the JavaScript prototype inheritance mechanism to allow my RenderTree object to inherit the ListLinks object's properties and methods, without throwing all sorts of annoying bugs at me.
The trouble is, because the ListLinks constructor takes arguments, I can't create an instance of the ListLinks object and use that as my prototype in code such as:
RenderTree.prototype = new ListLinks(object);
because doing so forces ALL instances of RenderTree objects to have the 'content' property set to the same value, and even attempting explicitly to modify that value in created instances fails. Yet, without doing something of the above sort, I can't change the identity of the instantiated objects - they retain the identity of a ListLinks object (the parent), instead of acquiring the identity of the child (the RenderTree object), which was the whole point of using the above, and the subsequent:
RenderTree.prototype.constructor = RenderTree;
This was done so that the RenderTree object could inherit ALL of the ListLinks objects' properties and methods, yet have additional functionality added to facilitate the generation of the rendering data I intend to be inserted into a binary tree of RenderTree objects, said objects having their own distinctive identity.
Now, one of the weird aspects of this, from my standpoint, is that whilst the 'content' property of the RenderTree object becomes, in effect, immutable when doing this, the same isn't true of the 'next' and 'prev' properties. Which suggests to me that there's some horrible inconsistency lurking at the heart of the inheritance mechanism that will simply make me want to go back to class based languages, that don't exhibit this annoying behaviour. Performing the above task in a language such as C++, defining a ListLinks Class and then defining a RenderTree Class as an extension thereof, doesn't drop this unwanted hassle in my lap.
Now, to compound the issue, I've seen no less than four different expositions on the subject (two of them from here, as it happens), including using Object.create(), using super constructor invocation (this was covered in more detail on the page of one Ben Nadel), and using fake constructors. None of them I've tried has worked. All that happens is that previous methods that mostly worked in the old code end up being broken spectacularly when I try one of the new methods. Indeed, I initially learned about the whole business from the web page of someone called Toby Ho (I would have posted a link, but I've just been told I can't have two webpage links in my post, all helping to add to the frustration of trying to solve this problem, thank you), but that page was of no help with my particular problem either, other than solving the matter of allowing me to have class method functionality in my code.
Now, given the huge amount of frustration I've had over this, is it too much to ask, to see someone provide me with an explanation of this inheritance mechanism that [1] is in accord with the observations I've made above, [2] produces something that works, and [3] demonstrates that someone out there does actually understand what it's doing? Only I'm increasingly coming to the conclusion that whoever designed the latest incarnation of JavaScript just made up whatever looked good at the time, then threw it into the interpreter without giving a hoot about whether or not programmers trying to use it could make any sense of it.
If I can't alight upon some means of achieving what should be something trivial, and has been trivial in class based languages I'm familiar with, then I think I'll relegate JavaScript to the bin as far as serious work is concerned.