Search code examples
javascriptinheritancemulti-level

Multi Level Inheritance in Javascript


I am trying to mock inheritance in Javascript using prototype.

I have a function named Model and a type of model => Item.

var Model = function() { 
   this.names = ["name1", "name2"]; 
} 
Model.prototype.Item = function(args) { 
   this.init = function(item_name) { 
      this.names[0] = item_name; // ERROR: Cannot set property '0' of undefined
   } 
}
var m = new Model();
var i = new m.Item();
i.init("New Name"); // ERROR: Cannot set property '0' of undefined

How can I access names array from init() function above?


Solution

  • Inheritance in Javascript is tricky! Read this post for a great explanation of traditional object oriented inheritance in Javascript: http://blog.slaks.net/2013-09-03/traditional-inheritance-in-javascript/.

    var Model = function () {
        this.names = ["name1", "name2"];
    };
    
    var Item = function () {
        //When inheriting in Javascript you must 
        //call the inherited function's constructor manually.
        Model.call(this);
    };
    
    //Inherit Model's prototype so you get all of Model's methods.
    Item.prototype = Object.create(Model.prototype);
    Item.prototype.constructor = Item;
    
    Item.prototype.init = function (item_name) {
        this.names[0] = item_name;
    };
    
    var Employee = function () {
        Model.call(this);
    };
    
    Employee.prototype = Object.create(Model.prototype);
    Employee.prototype.constructor = Employee;
    
    var myItem = new Item();
    myItem.init("New Name");
    //prints New Name, name2
    console.log(myItem.names);
    
    
    var myEmployee = new Employee();
    //prints name1, name2
    console.log(myEmployee.names);
    

    Analogous code in a more traditional object oriented language (C#):

    public class Model
    {
        public Model()
        {
            this.Names = new[] {"name1", "name2"};
        }
        public string[] Names { get; set; }
    }
    
    public class Item : Model
    {
        public Item() : base() { }
    
        public void init(string item_name)
        {
            this.Names[0] = item_name;
        }
    }
    
    public class Employee : Model
    {
        public Employee() : base() { }
    }
    
    var myItem = new Item();
    myItem.init("New Name");
    //prints New Name, name2
    Console.WriteLine(String.Join(",", myItem.Names));
    
    var myEmployee = new Employee();
    //prints name1, name2
    Console.WriteLine(String.Join(",", myEmployee.Names));