1

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.

David Edwards
  • 794
  • 8
  • 13
  • `RenderTree.prototype = Object.create(ListLinks.prototype)` – elclanrs Sep 25 '15 at 05:50
  • `Object.create` is the way to go, see also http://stackoverflow.com/q/17392857/218196. The reason why `next` and `prev` work is likely because you are setting them later after the object is created. But without seeing a more complete exmsplem that's just a guess. You clearly invested some time to figure this out, which is great, but this is actually too much text and too few code. – Felix Kling Sep 25 '15 at 05:52
  • Well since the ListLinks constructor explicitly sets the 'prev' and 'next' properties, within it, I'm again puzzled as to why they remain mutable, yet the 'content' property, because it's set by an invocation argument, becomes immutable, the moment I set about using the supposedly "standard" method for re-casting the object's identity. – David Edwards Sep 25 '15 at 06:13
  • `content` is not immutable. It behaves exactly like the other properties. Again, because we don't know what you are actually doing, there is not much more we can say about it. – Felix Kling Sep 25 '15 at 06:19
  • Well every time I test the code in question, the 'content' property never changes from whatever it was set to in the line: RenderTree.prototype = new ListLinks(object); even when, in subsequent methods attached to the RenderTree object, I write code performing explicit writes to that property. Unfortunately I've just been told that the code I wanted to supply as an example is too long for the comments box. – David Edwards Sep 25 '15 at 06:28
  • How about editing your question and providing a minimal example that reproduces the issue? You can also remove the unneccessary rant from the question to make it more concise. – Felix Kling Sep 25 '15 at 06:42
  • Here i am, 2½ months later, I'm now up to having read **nine** different accounts of prototypal inheritance, ALL telling me different things, and NONE of them working for me. I'm still waiting to see if anyone actually understands how this language actually works, because right now, I'm increasingly concluding that it's been made up as the authors went along, without any real planning behind it. This should be telling you that my "rant" IS necessary, because no one I encounter says anything consistent on this matter. – David Edwards Dec 04 '15 at 06:55

0 Answers0