with Imagination: by Dustin Diaz

./with Imagination

A JavaScript, CSS, XHTML web log focusing on usability and accessibility by Dustin Diaz

What’s new in JavaScript?

Wednesday, May 16th, 2007

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.

16 Responses to “What’s new in JavaScript?”

  1. Dean Edwards

    Augmentation is slower than inheritance. I’m not really sure what you are getting at with this article.

  2. Dustin Diaz

    augmentation and inheritance aren’t parallel schools. The point is you also receive inheritance through augmentation instead of consistently creating ‘new’ objects.

  3. Dean Edwards

    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 new operator is that it avoids creating large inheritance chains and saves on creating lots of unnecessary objects. Functions are objects too.

  4. Dean Edwards

    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. :-)

  5. Dustin Diaz

    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.

  6. Peter Michaux

    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.

  7. Geoff Moller

    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.

  8. Grey

    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?

    
    function nue(f){
       var args = [].slice.call(arguments, 1);
       f.prototype.constructor = f;
       f.apply(f.prototype, args);
       return f.prototype;
    };
    
    function y(){}; // set up inheritance
    function x(){};
    x.prototype = new y();
    
    alert(x.prototype.constructor); // intial value == y
    void(new x());                  // construct with new keyword
    alert(x.prototype.constructor); // new value == y
    void(nue(x));                   // construct through "nue"
    alert(x.prototype.constructor); // new value == x
    
  9. Dustin Diaz

    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:

    function F() { }
    var o = nue(F);
    o.foo = 'hello'; // set prototype properties to 'F'
  10. Claude

    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?

  11. Grey

    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”?

  12. Little talker

    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!

  13. Ben

    Disclaimer: “I might be viewing this concept the wrong way.”

    This is not inheritance, it’s aliasing.

    
    function F(){}
    var x = nue(F);
    x.id = 'x';
    x.shout = function() {alert(this.id)}
    var y = nue(F); // A new instance... not really.
    
    x.shout()
    y.shout() // alias!
    

    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.

  14. Isaac Z. Schlueter

    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. :)

  15. Finally Graduated

    [...] What?s new in JavaScript? [...]

  16. Paul

    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.

Get "JavaScript Design Patterns"

"As a web developer, you'll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power waiting to be unlocked--JavaScript is capable of full object-oriented capabilities, and by applying OOP principles, best practices, and design patterns to your code, you can make it more powerful, more efficient, and easier to work with alone or as part of a team."

Buy JS Design Patterns from Amazon.com Buy JS Design Patterns from Apress

Submit a Prototype

All content copyright © 2003 - 2007 under the Creative Commons License. Wanna know something? Just ask.

About | Archives | Blog Search

[x] close

Loading...

Submit a prototype

By checking this prototype I agree that I am not submitting false credentials, pornography, or a hate crime website. I also understand that by submitting my entry I may or may not be accepted, and if accepted, my entry may be taken down at any given time if I violate these terms.