0

What I am trying to do is inherit the id and name from the TField and override the render function of the TField. I want to know if this is the stardard way to implement inheritance in JavaScript.

var TField=function(jData)
{
   this.id=jData.id;
   this.name=jData.name;
   this.attributes=jData.attributes;
   this.render=function(){
      alert('TField render.');
   };
};

var TChildField=function(jData)
{
    var t= new TField(jData);
    t.render=function(){
       alert('TChildField render.');
    }
    return t;
}

var tobj={id:"1",name:"test",attribute:{}};


var c= new TChildField(tobj);
alert(c.id);
alert(c.name);
Trott
  • 66,479
  • 23
  • 173
  • 212
Joe.wang
  • 11,537
  • 25
  • 103
  • 180
  • I suggest you to have a look to some Javascript resources: - http://eloquentjavascript.net/ (chapter 8 in particular) - http://addyosmani.com/resources/essentialjsdesignpatterns/book/ – Alberto De Caro Apr 08 '13 at 08:27
  • Good, It definetely what I need. Any idea about the code . Is there anything wrong with it ? thanks. – Joe.wang Apr 08 '13 at 08:35

2 Answers2

1

This is more like decorator pattern inheritance. But its working as you expected, just call c.render(). To do classical prototypal inheritance, just assign TField to be prototype of TChildField. Look at Understanding prototypal inheritance in JavaScript

Community
  • 1
  • 1
Grzegorz Kaczan
  • 21,186
  • 3
  • 19
  • 17
1

Firstly, it probably is a good idea to remove the render definition from the constructor and add it to the prototype directly with:

TField.prototype.render=function(){
      alert('TField render.');
};

Secondly, to set up inheritance of the constructor, use:

var TChildField=function(jData)
{
    TField.call(this,jData)
}

Then, link the the two prototypes

TChildField.prototype=Object.create(TField.prototype)

Finally, overwrite render() for TChildField

TChildField.prototype.render=function(){
      alert('TChildField render.');
};


var TField=function(jData)
{
   this.id=jData.id;
   this.name=jData.name;
   this.attributes=jData.attributes;

};

TField.prototype.render=function(){
      alert('TField render.');
};

var TChildField=function(jData)
{
    TField.call(this,jData)
}

var tobj={id:"1",name:"test",attribute:{}};
TChildField.prototype=Object.create(TField.prototype)
TChildField.prototype.render=function(){
      alert('TChildField render.');
};
var c= new TChildField(tobj);
alert(c.id);
alert(c.name);
Manishearth
  • 14,882
  • 8
  • 59
  • 76
  • @GrzegorzKaczan: Well, I copied the prototype of the parent class to the child class. This makes it scalable, since then I can add more functions and they will be automatically inherited. – Manishearth Apr 08 '13 at 08:44
  • I found this is the way the w3cschool javascript tutorial recommended. – Joe.wang Apr 08 '13 at 09:02
  • Hi, @Manishearth, Could I put the code `TChildField.prototype.render=function(){..};` inside the `var TChildField=function(jData){...};` ? – Joe.wang Apr 08 '13 at 09:13
  • @Joe.wang: No, don't do that. Not sure if you _can_, but it may lead to unexpected results. And it will get overwritten when we link the prototypes anyway. – Manishearth Apr 08 '13 at 09:17
  • @Manishearth , I just want all the code is closed in the class definiton just like the classical inheritance in the oop language like `c#` or `java`. – Joe.wang Apr 08 '13 at 09:20
  • @Joe.wang: This isn't Java/C#. Prototypal inheritance is different, it's better if you define your functions separately. The var `TField=function(...` is _not_ a class definition, it's a _constructor_ definition. Would you stuff all your method definitions in a constructor in Java? Probably not ;-) – Manishearth Apr 08 '13 at 09:23
  • The problem of this way I can see is `TChildField.prototype.render=function(){..};` can't use the parameter of the constuctor definition directly. I doubted it can only utilize the public field .like `this.id` , `this.name` etc. so . that will cause many public field or global field exist without need. – Joe.wang Apr 08 '13 at 09:29
  • @Joe.wang: I don't understand what you're saying. It _can_ access `this.id`, etc. See https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript – Manishearth Apr 08 '13 at 09:30
  • @Manishearth I mean can I use the `jData` in the function `TChildField.prototype.render=function(){..};`? I don't want it be the public field . – Joe.wang Apr 08 '13 at 09:33
  • @Manishearth I know It can access the public property like `this.id`, etc. – Joe.wang Apr 08 '13 at 09:37
  • @Joe.wang: Well, no. What's wrong with making it a property of the object? Thing is, you won't have a proper inheritance _and_ have private data like this. The only way out is to just define the two classes separately, and don't link them in any way. – Manishearth Apr 08 '13 at 09:39
  • @Manishearth I can see the way of defining two classes probably equal with most of the code is not good idea .. It will against OOP and DRY. – Joe.wang Apr 08 '13 at 09:48
  • @joe well, data hiding never really was necessary in JS. It's not againt oop, oop doesn't _have_ to have private members. – Manishearth Apr 08 '13 at 10:02
  • But yeah, defining two classes is against dry. Which is why I didn't answer with that :) – Manishearth Apr 08 '13 at 10:02