Aug 22, 2005

Raising Hell

David flanagan blog about how people should call JavaScript pseudo-classes, and as I got a lot to say about that, instead of a comment I will post here.

They are no class in ECMAScript, and this is cleraly explained in the ECMA-262 specification.


4.2.1 Objects
ECMAScript does not contain proper classes such as those in
C++, Smalltalk, or Java, but rather, supports constructors
which create objects by executing code that allocates storage
for the objects and initialises all or part of them by
assigning initial values to their properties.

All constructors are objects, but not all objects are
constructors.

Each constructor has a Prototype property that is used to
implement prototype-based inheritance and shared properties.


And that's why I name that post Raising Hell, this is not helping ECMAScript to not be clear and precise about the language mecanism.

I'm already experiencing that a lot with ActionScript, and now after few years I see the mess caused by bad terminology.

To resume that mess, from Flash 5 to Flash 6, Macromedia have used ActionScript which implements ECMA-262, and then at Flash 7 time, they have moved to ActionScript 2, based on the not finished ECMAScript 4 proposal.

They did that because they wanted to give that "professional" touch to their software, to attract developpers from other environment as Java/C#/etc.

The result is that people using ActionScript believe that they use a real class-based language, and so instead of thinking their code in prototype-based terms, they think it as if they were programming Java or some class-based equivalent.

THIS IS PLAIN WRONG.

First of all, I think it's irresponsible to implement a language on an unfinished draft, this can lead only to very strange backward language compatibility, just compare ActionScript 2 and JScript.NET and you can already see that they are very different in implementation and so incompatible even if based on the same draft.

Second, with ECMA-262 we got a prototype-based language which can already mimic the class-behaviour, what would be the use to cut ourselves from features that class-based language do not have ?

I gonna give a ridiculous exemple that I experienced with people trying to think in Java with ActionScript 2: the singleton pattern

here how people implement that pattern in ActionScript 2

   class Singleton
     {
     private static var _oInstance:Singleton;
    
     private function Singleton() {}
    
     public static function getInstance():Singleton
       {
       if(_oInstance == undefined)
         {
         _oInstance = new Singleton();
         }
      
       return _oInstance;
       }
    
     public static function release():Void
       {
       if(_oInstance)
         {
         delete _oInstance;
         }
       }
   }


Yes, they copy how it's done in Java, and yes it's wrong, not because Java do it wrong, but it's wrong to do like that for ECMAScript which is not a class-based language. (as a side note, ActionScript 2 is not a real class-based language, only it's syntax is class-based)

With a language based on prototype you work on the object level, you don't need to define a class to create one-instance only of an object, the only thing you need to do is to create the object and directly assign methods and properties to it.

   Singleton = {};
  
   Singleton.someProp = 12345;
  
   Singleton.someMethod = function( /*Number*/ num )
       {
       return this.someProp + num;
       }


that's the difference, in Java to obtain a singleton you have to instanciate it, they are no other way than to use a class. So off course to be sure to have only one instance of a class you will need to enforce that with a getInstance method for the class, or a similar mecanism.

But in ECMAScript, you do not need to instanciate your unique object, you just have to declare it, and just because you don't instanciate it with a class (or even a constructor) you're sure that it is indeed unique.

I requote
not all objects are constructors


And it's for things like that, that it is so important to use the good terminology in ECMAScript, you don't want people to think in class-based terms and confuse them thinking they can have the same logic as in Java.

You want them to think their code closer to the object, not closer to the class, you want them to see that the objects either literals or built with constructor function are different than the ones created in a class-based language, you want them to see that they look the same but the inner mecanism which had created them is not the same at all.

4.2.1 Objects
...
Every constructor has an associated prototype, and every
object created by that constructor has an implicit reference
to the prototype (called the object’s prototype) associated
with its constructor.
...
In a class-based object-oriented language, in general, state
is carried by instances, methods are carried by classes, and
inheritance is only of structure and behaviour.

In ECMAScript, the state and methods are carried by objects,
and structure, behaviour, and state are all inherited.

All objects that do not directly contain a particular
property that their prototype contains share that property
and its value.


To really see the difference of the prototype-based mecanism, read that paper which explain all in details.

The main idea being that a prototype-based language allows to create object without class, and that's why imho you can not use the class terminology inside ECMAScript.


References:

  • Prototype based languages
    Billborn and Mallela Srinivasa Rao
    PDF
    (if this document get moved, contact me to have a copy, I keep everything :))
  • Raising Hell
    Run-D.M.C. - Raising Hell (1986/1/1)


read more ...