views:

328

answers:

3

Hello

I'm trying a few different approaches to Javascript inheritance at the moment. I have the following code:

('borrowed' from http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm)

KV = {};

KV.extend = function(subClass, baseClass) {
       function inheritance() {}
       inheritance.prototype = baseClass.prototype;

       subClass.prototype = new inheritance();
       subClass.prototype.constructor = subClass;
       subClass.baseConstructor = baseClass;
       subClass.superClass = baseClass.prototype;
    }

function GridView() {
        var _ownerElement;
    }

    GridView.prototype.getOwnerElement = function() {

        return this._ownerElement;
    }

    GridView.prototype.setOwnerElement = function(ownerElement) {
        this._ownerElement = ownerElement; 
    }

    GridView.prototype.initialize = function() {
        this.setOwnerElement('test');
    }


function StreetGridView(dataURL, ownerElement) {
        StreetGridView.baseConstructor.call(this);

        StreetGridView.superClass.initialize();

        StreetGridView.superClass.setOwnerElement(ownerElement);


}

// subclass StreetGridView
KV.extend(StreetGridView, GridView);

Now, when I create an instance of StreetGridView, I can call getOwnerElement() on it no problem. Everything works as expected.

HOWEVER

When I create ANOTHER instance, any changes made to instance 2 are reflected back in instance 1.

I know this is the main problem with using prototypes as the share instance information. I've been racking my brains this morning but wondered if there was someone out there who could point me in the right direction!

Thanks

+1  A: 

Inspiration strikes!

I couldn't get that pattern to work, so please let me know if you can spot what is wrong with it. But moving things around and using Combination Inheritance, I seem to have solved the problem.

I've included the following code and left this post on the forum to help others in future.

function GridView() {
        var _ownerElement;
    }

    GridView.prototype.getOwnerElement = function() {

        return this._ownerElement;
    }

    GridView.prototype.setOwnerElement = function(ownerElement) {
        this._ownerElement = ownerElement; 
    }

    GridView.prototype.initialize = function() {
        this.setOwnerElement('test');
    }

    function StreetGridView() {

        GridView.call(this);
    }

    StreetGridView.prototype = new GridView();

    StreetGridView.prototype.initialize = function(dataURL, ownerElement) {

        this.setOwnerElement(ownerElement);


        /* Constructor Code */

        $(this.getOwnerElement()).flexigrid
      (
          {
              url: dataURL,
              dataType: 'json',
              colModel: [
              { display: '', name: 'view', width: 20, sortable: true, align: 'center' },
           { display: 'USRN', name: 'USRN', width: 80, sortable: true, align: 'center' },
           { display: 'Street', name: 'Street', width: 260, sortable: true, align: 'left' },
           { display: 'Locality', name: 'Locality', width: 200, sortable: true, align: 'left' },
           { display: 'Town', name: 'Town', width: 200, sortable: true, align: 'left' },
           { display: 'Open', name: 'Actions', width: 30, sortable: false, align: 'center' }
           ],
              sortname: "USRN",
              sortorder: "asc",
              usepager: true,
              title: 'Streets',
              useRp: true,
              rp: 5,
              showToggleBtn: false,
              width: 'auto',
              height: 'auto'
          }
      );
    }
Duncan
I'm glad you got to find you own solution, but this code as posted using jQuery ajax doesn't seem to address your original question about inheritance as posted. You may need to revise your original question and then accept your own answer.
Jose Basilio
You should be aware that you are calling the GridView constructor twice (which may not be a problem), but if you'd like the efficiency of just once, you can replace your line: StreetGridView.prototype = new GridView();with a call to a helper method: instatiatePrototype(subConstructor, supConstructor)...you're implementation to instantiatePrototype is actually pieces of your first post ;) Good luck. If you have trouble, refer to the Zakas book page 181!
Rob
A: 

See here and here for info :)
Also use a framework like Prototype or Dojo.
They make life much easier.

the_drow
I must be dumb because I have real trouble following Douglas' articles!
Matthew Lock
+2  A: 

the_drow:

I left a comment above about calling the super constructor twice with your solution - but feel a bit bad about leaving you hanging on the implementation of inheritPrototype. First of all, credit to Nicholas Zakas as this is me paraphrasing his book Professional JavaScript for Web Developers, 2nd Ed (page 181):

function inheritPrototype(sub,sup) {
  var proto = object(sup.prototype);// you'll need an object create method ;)
  proto.constructor = sub;
  sub.prototype = proto;
}

Now replace your:

StreetGridView.prototype = new GridView();

with,

StreetGridView.prototype = inheritPrototype(StreetGridView,GridView);

and you've only called your GridView constructor once! But you'll notice the object method. You'll need something like:

function object(o) {
  function F(){};
  F.prototype = o;
  return new F();
}

If you've read any Douglas Crockford you've seen this one!

Shameless Plug: This stuff is hard to grok and is the exact reason I'm doing an essay on TDD JavaScript and the whole second part has a bunch of unit tests of inheritance patterns. I'm specifically examining the Zakas and Crockford books on object creation and inheritance. You don't have to read my essay (it's currently in Open Office .odt format), but you could do a lot worse than to just download my code and read it in 2 minutes! Here's the link: My Free Book

Rob
Thanks .I have downloaded your book and it seems good.Have you thought about writing a chapter about Mocking, Wrting UI Widgets with TDD ?
mcaaltuntas