What’s new in JavaScript?
Sparked from a late night conversation that I had with my co-author-in-crime, we touched a bit on what prototypal inheritance means for JavaScript, and the role of a constructor function since, if you don’t mind me saying, they somewhat contradict each other other. JavaScript has a special operator known as new, which essentially does only _two_ real things for you that couldn’t otherwise accomplish without it (although, we might not even possibly need it anyway).
The first is simple. You can’t achieve instance variables as you do in a classical language. All objects are mutable, and all objects inherit from objects. When you change an object high up in the chain, all objects beneath it, inherit from it through delegation (not concatenation). However “instance variables” is a classical paradigm that in one sense, conflicts with the nature of a prototypal language. Douglas Crockford touches on this briefly in his few words about prototypal inheritance and recommends a utility function to achieve this type of inheritance.
The second is rather somewhat obvious as well. We have no real way checking against first class object instances through the instanceof operator. But here we are, conflicted again. If you are in fact concerned about what kind of object you’re working with, you can look at your constructor’s name property.
All in all, by the end of the night, we concluded that there really isn’t anything entirely special in nature about the new operator, and that we could write our own special version of it that allows us to embrace true prototypal inheritance:
prototypal “new” in JavaScript
function nue (f) {
var args = [].slice.call(arguments, 1);
f.prototype.constructor = f;
f.apply(f.prototype, args);
return f.prototype;
}
Embracing prototypal inheritance
The idea is pure, and allows you to truly utilize and incorporate what prototypal inheritance is all about. JavaScript, I believe, was not meant to be a classical language with formal notions of classes, although new gives us a taste of it. So on the other hand, we do not need to “subclass” objects that introduce tightly coupled relationships. Even for classical programmers who come from C, Python or Java, one should know that deep hierarchies are bad, shallow ones are better. JavaScript allows us to avoid hierarchies entirely. So why do it? We can after all, just augment from other objects as necessary, and introduce new objects when needed. JavaScript is unequivocally, a utopian language. It is communistic in nature, meaning that all objects can live in harmony with one another, each sharing the same resources allowing it to be a very, very fast language.
There was in fact “much” more to our conversation, but I’ll provide that commentary into our book. Cheers.













May 16th, 2007 at 4:35 pm
Augmentation is slower than inheritance. I’m not really sure what you are getting at with this article.
May 16th, 2007 at 5:10 pm
augmentation and inheritance aren’t parallel schools. The point is you also receive inheritance through augmentation instead of consistently creating ‘new’ objects.
May 16th, 2007 at 5:31 pm
I’m still not following you. You don’t “receive inheritance through augmentation”. You augment. Once you’ve augmented, it’s over. You can’t change the inheritance chain later in the day. Your “nue” function actually creates several objects. A new function object, a new object in an inheritance chain and a new object to operate on. How is that better? For javascript implementations that become unstable when you create large numbers of objects (e.g. IE) then this will just treble the speed at which your application becomes unstable. What’s “special” about the
newoperator is that it avoids creating large inheritance chains and saves on creating lots of unnecessary objects. Functions are objects too.May 16th, 2007 at 5:38 pm
Oops. I misread you’re “nue” function. But my point still applies (creating unnecessary objects to avoid instantiation is not an improvement).
And since when did inheritance become bad? I missed that meeting. :-)
May 16th, 2007 at 6:15 pm
Dean, inheritance not bad. In fact, it’s great (I hope I didn’t make it sound like it’s bad, because I meant the exact opposite). I’m talking about Prototypal inheritance vs classical inheritance. If there was a bad inheritance meeting, we need to make sure that meeting never happens again.
May 17th, 2007 at 10:02 am
It seems to me that prototypal inheritance is a difficult thing to implement purely or internalize mentally. Even people that use JavaScript frequently and are interested in the OO constructs spend a lot of time bending the prototypal paradigm to do their bidding rather than using it in it’s most natural form. Even after quite a long time using/thinking/worrying about OOP in JavaScript I’m still waiting for the big “Ah-Ha!” moment where I won’t ever want to use the JavaScript OOP paradigm in a classical style.
Last night I was reading one of the early papers on the Self programming language just trying to get another perspective on why prototypal inheritance is “so great.”
http://research.sun.com/self/papers/self-power.html
It seems to me that even the inventors of Self just sort of give up at one point and state that they really do need something like a class even with prototypal inheritance (page 8 line 11 of the document linked to from that URL.)
It is an odd beast this prototypal inheritance is.
May 17th, 2007 at 10:41 am
Inheritance rules, but long inheritance chains have always been a pain for me and mine - I think this is a battle that will always be fought. Brittleness aside, if we (me and the rest of the “average” we) we able to hold larger sequences of abstractions in our head over the short and long term, longer inheritance chains would probably be less of a gotcha.
May 19th, 2007 at 12:56 pm
Excuse me, but it seems like you change the constructor of the function’s prototype object. First I thought I was wrong, then I checked in the browser. Then I thought maybe the browser is wrong. But it’s the same on Gecko, Presto and Trident.
Also, the local variable “args” is unnecesary (though it helps understanding the code). At the moment, as it stands, with the args “fix”, this script snipped doesn’t create a new object, it merely returns the prototype object of the function (and makes changes to it along the way, boo!).
Spontaneously, I have no idea as to how to produce a new instance of the prototype object except copying it to a temporary function and using “new” on it.
You want proof?
May 19th, 2007 at 3:07 pm
Hi Grey,
You’re looking at this from the wrong point of view. This is exactly the point I’m trying to make in this post. Your approach of making instances is using a classical pattern, and not embracing prototypal inheritance. ‘new’ is in fact a brand new object, and yes, I understand that, and how it works. But here we can avoid that with ‘nue’ and instead work with inheritance through the prototype all the time. For this particular case, you wouldn’t ever set an object’s prototype to a nue instance. But instead, like this:
May 19th, 2007 at 7:57 pm
When you say that “JavaScript is unequivocally, a utopian language. It is communistic in nature, meaning that all objects can live in harmony with one another,” are you saying that all JS objects are equally miserable?
May 19th, 2007 at 9:23 pm
And what purpose does this fulfill, may I ask? That’s kind-of “reverse inheritance”, parents inheriting from their children.
With any change you apply to the prototype object, you make changes to the parent and any children of the parent (I mean refs to the Functions’s prototype object, not classical children).
This doesn’t make sense to me. OOP is about reuse, imho. Where is the reuse?
And suppose “new” and “nue” are not parallel models…. where is nue to use? I.e. what is the use case? You said short inheritance chains. Could you come up with ine example where using “nue” is better than “new”?
May 22nd, 2007 at 7:02 am
Maybe I’m not in the league just yet… How and why would you use this technique in a real world situation? Could anyone please provide a simple example or point me to one?
Thanks!
June 29th, 2007 at 4:06 am
Disclaimer: “I might be viewing this concept the wrong way.”
This is not inheritance, it’s aliasing.
Both x and y cannot have unique properties, since both are references to F’s prototype. The “nue” alternative of “new” is inappropriate and there are less abstract ways to create a reference…
furthermore:
var F = function(){ this.id = ‘F’; this.shout = alert(this.id); } x = nue(F); x.shout(); y = nue(F); // F breaks here because it tries to set “F.prototype.prototype.shout”. y.shout(); x.shout();Then again… maybe I’m looking at it all wrong.
September 20th, 2007 at 4:48 pm
PS: I completely agree with the spirit of what you’re saying here. Every word. But the nue function doesn’t do what you seem to think it does.
And yes, it turns out I did steal extend verbatim from Crockford. At the page you linked to, no less. :)
September 26th, 2007 at 5:40 pm
[…] What?s new in JavaScript? […]
October 30th, 2007 at 3:30 pm
FYI (off topio) Your “Change Layout for your reading convenience?” is cool.
But… Change it, then click on a link on your page and come back. It’s not saved.