Extending Classes in HDi - not working in Emulator

We're seeing some weird behavior on the Toshiba Emulator. Object oriented javascript runs well in HDi - you can have multiple extensions of a class and they act as expected. However when this script was run in the Emulator all extended classes act like the very last class loaded.

So for example if a Food class is extended to veggie, fruit and grain; in they Emulator they all act like the grain class (assuming it was the last one loaded).

Am I missing something in the ECMA spec that prohibits object oriented javascript





Answer this question

Extending Classes in HDi - not working in Emulator

  • swapna_n

    Hey Will,

    Here is what the spec says

    ECMAScript supports prototype-based inheritance. 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. Furthermore, a prototype may have a non-null implicit

    reference to its prototype, and so on; this is called the prototype chain. When a reference is made to a

    property in an object, that reference is to the property of that name in the first object in the prototype

    chain that contains a property of that name. In other words, first the object mentioned directly is

    examined for such a property; if that object contains the named property, that is the property to which

    the reference refers; if that object does not contain the named property, the prototype for that object is

    examined next; and so on.

    (see page 4.2.1 of the ECMA specification for all the details)

    Unfortunately prototyping is not found in proper OO languages such as small talk and Java. (I haven't seen this ability in .NET yet, but I could be wrong)

    JS orignially wasn't an OO language but since 2000 (at least in my experiance) you could achive OO (no prototyping needed) with IE 4.0 and ever since then i think it has been used. (Maybe earlier I am not sure). Maybe this is what you are doing, or maybe it is a bug in the emulator Hope that helps

    Denny B



  • OptikConnex

    I assume initialize it is added to Object.prototype at some stage Are you sure it is returning the same object every time, or is it just incorrectly binding the this reference every time The create function should return a new Function object every time, and if you then use that function in a new expression you should get a new this reference every time.

    IMHO you should let a language be itself, not try to make it look like C++ :-)



  • Syri

    You can read Part 1 and Part 2 of my series on my blog (I still haven't finished writing Part 3...):

    http://blogs.msdn.com/ptorr/archive/2006/06/13/630208.aspx

    http://blogs.msdn.com/ptorr/archive/2006/06/19/638195.aspx

    ECMAScript does not support traditional class-based programming, but prototype inheritance should work fine in HD DVD.

    Can you post the code in question (or rather a simplified version of it that demonstrates the error)



  • Jim Perry

    No, right now I am adding the initialize methods to the classes after I create them with Class.create (see example below). I was under the impression that the HD-DVD implementation of ECMAScript didn't allow built-in objects like Object to be modified.

    It does appear that Class.create returns the same Function object every time. Here's a simplified example:

    var Obj = {
    extend: function(destination, source) {
    for (property in source) {
    destination[property] = source[property];
    }
    return destination;
    }
    };

    var BaseClass = Class.create();
    Obj.extend(BaseClass.prototype, {
    initialize: function() {},
    getClassName: function() { return "BaseClass"; }
    });

    var DerivedClass = Class.create();
    Obj.extend(DerivedClass.prototype, BaseClass.prototype);
    Obj.extend(DerivedClass.prototype, {
    initialize: function() {},
    getClassName: function() { return "DerivedClass"; }
    });

    objectOne = new BaseClass();
    objectTwo = new DerivedClass();


    As I mentioned before, this works as expected in HDiSim. However, on Toshiba's emulator, getClassName would return "DerivedClass" for both objects, so it seems that Class.create returns the same Function object both times.

    My workaround is just to declare classes as function() { this.initialize.apply(this, arguments); } instead of using Class.create. This seems to work correctly in both environments.

    With regards to letting a language be itself, one of the reasons I like JavaScript/ECMAScript is its flexibility and the ability to mix procedural, object-oriented, and functional paradigms. Aside from a few glitches like this I've had, I think that using a object-oriented framework built in this fashion will really increase the speed of our development.

    But to each his own - unless you know of any issues with the ECMAScript implementations of other players that would cause problems with code like this.

  • Starck

    I've been working with Will on this project and here's the issue I found.

    I'm using some code from the Prototype JavaScript library enable the class-based style of programming. Here's the the bit I've been having a problem with:

    var Class = {
    create: function() {
    return function() {
    this.initialize.apply(this, arguments);
    };
    }
    };

    I create each class using this Class.create method and then use another method to "extend" classes that copies all of the methods from one object's prototype to another's.

    In HDiSim, the Class.create method returns a new object for each call, so everything works as expected. When running on the Toshiba emulator however, it returns the same object every time, so when I later extend a class, the methods of the last defined class override the methods of all previously defined classes.

    The workaround I'm using now is just to explicitly define the constructor of each class rather than using Class.create, but I've been wondering which ECMAScript implementation is correct.

  • SrinivasParimi

    I know it's just an example, but that's just a lot of overhead just to do this:

    function base() {};
    base.prototype.initialize = function base_init() { print("base init"); };
    base.prototype.getClassName = function base_gcn() { return "base"; };

    function derived() {};
    derived.prototype = new base();
    derived.prototype.getClassName = function derived_gcn() { return "derived"; };

    I will try to take a look on the Toshiba later today.



  • karthik.sr

    Peter, were you able to repro this behavior on the/your emulator


  • steveareno

    OK, this is rather tricky but is perfectly spec compliant.

    If you look at sections 13.1 and 13.2 of the ECMAScript specification, you will see that when you use the same FunctionBody more than once, an implementation can choose whether or not to create a new Function object or whether to "join" a new dummy Function object to the existing one.

    JScript obviously chooses to create a new Function object every time, but Toshiba chooses to join them. Unfortunately, the implementation of the joined objects appears flawed,but that's neither here nor then when it comes to this particular issue -- by spec, they are allowed to make the two objects "the same" and thust they share the same prototype.

    Here is a much simpler repro:

    function MakeAConstructor()

    {

    return function() {};

    }

    var Constructor1 = MakeAConstructor();

    var Constructor2 = MakeAConstructor();

    // false in JScript; should be true if joined properly,

    // but also false in the Toshiba player due to a bug

    print(Constructor1 == Constructor2);

    // false in JScript, but true on Toshiba since they are

    // (at least partially) joined

    print(Constructor1.prototype == Constructor2.prototype);

    This is a drawback to the style of coding you are using where a factory method is used to create constructors; I highly recommend moving to the more traditional method.



  • Extending Classes in HDi - not working in Emulator