Grow your CSS skills. Land your dream job.

need help with javascript inheritance and nested objects.

  • # November 16, 2009 at 10:54 pm

    I am updating on a coding model I created last week, and am running into issues with nested objects and inheritance.

    I am trying to learn Javascript (particularly OOP) from a series of screencasts by Douglas Crockford. I have developed a theoretical "game" to build to illustrate it to myself better, and learn by example.

    I must be misunderstanding how inheritance works, because my code is not producing the results I thought it would.

    Here is what I have, followed by an explanation of my understanding.
    Code:

    Code:
    $(function() {

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

    soldier = {
    pointsCost: 0,
    movement: “1 Infantry Block”,
    validTargets: {},
    weapons: {
    “Main Weapon”: {
    “Weapon Type”: “M4 Carbine”,
    “Fire Range”: 12
    },
    “Secondary Weapon”: {
    “Weapon Type”: “JCP .45″,
    “Fire Range”: 3
    }
    }
    };

    var rifleman = object(soldier);
    rifleman.pointsCost += 10;
    rifleman.validTargets.target1 = “Infantry”
    rifleman.weapons[“Secondary Weapon”][“Weapon Type”] = “”;
    rifleman.weapons[“Secondary Weapon”][“Fire Range”] = “”;

    var heavyGunner = object(soldier);
    heavyGunner.pointsCost += 20;
    heavyGunner.validTargets.target1 = “Infantry”;
    heavyGunner.validTargets.target2 = “Light Armor”;
    heavyGunner.weapons[“Main Weapon”][“Weapon Type”] = “SAW M249″;
    heavyGunner.weapons[“Main Weapon”][“Fire Range”] = 12;
    heavyGunner.weapons[“Secondary Weapon”][“Weapon Type”] = “”;
    heavyGunner.weapons[“Secondary Weapon”][“Fire Range”] = “”;

    var sniper = object(soldier);
    sniper.pointsCost += 30;
    sniper.validTargets.target1 = “Infantry”;
    sniper.weapons[“Main Weapon”][“Weapon Type”] = “Savage .308″;
    sniper.weapons[“Main Weapon”][“Fire Range”] = 20;
    sniper.weapons[“Secondary Weapon”][“Weapon Type”] = “JCP .45″;
    sniper.weapons[“Secondary Weapon”][“Fire Range”] = 3;

    var demolitions = object(soldier);
    demolitions.pointsCost += 30;
    demolitions.validTargets.target1 = “Infantry”;
    demolitions.validTargets.target2 = “Light Armor”;
    demolitions.validTargets.target3 = “Artilery”;
    demolitions.validTargets.target4 = “Structures”;
    demolitions.weapons[“Main Weapon”][“Weapon Type”] = “SMAW MK153″;
    demolitions.weapons[“Main Weapon”][“Fire Range”] = 16;
    demolitions.weapons[“Secondary Weapon”][“Weapon Type”] = “M1014 Combat Shotgun”;
    demolitions.weapons[“Secondary Weapon”][“Fire Range”] = 1;

    var infantry = {

    rifleman: rifleman,

    heavyGunner: heavyGunner,

    sniper: sniper,

    demolitions: demolitions

    };

    console.log(infantry);

    });

    I start by creating an object function that accepts an object passed in, and sets it to the prototype of a constructor (that would allow me to create a new object linked to, and inheriting from, the initial passed in object)

    I initialized a solider object literal, and pass that into the object function while creating 4 new objects (rifleman, heavyGunner, sniper, demolitions)
    These four should inherit from and customize upon the soldier object.

    The way I understood inheritance is that the new objects (example. rifleman) would inherit properties from the old object (i.e. soldier) and change or add properties, affecting only the new (rifleman) object but not changing the old(solider) object.

    this works ok somewhat in my example, until it comes to nested objects.
    In the above example I have objects as values for some Object’s properties. (i.e. validTargets and weapons) When I change or add these, all of the new objects seem to inherit the last declarations, from demolitions, as if demolitions is actually changing that part of the soldier object so that the other’s inherit those properties.

    From my viewpoint, I expected these values to not be changed and that the 4 infantry types had no link to each other, but only to the soldier object.

    I apparently misunderstood something, or coded something wrong.

    Some minor notes:
    -I will be updating most of the "string" values to be objects, so for instance, the validTargets value of "Infantry" would actually be the infantry object, stating that any of the 4 solider types would be a valid target.
    – I intend to create weapons as their own viable objects in the future, and pass those objects instead of "strings"
    – I intend to extend this (once this is working) to create an armor object that contains armor type units, similar in structure to the infantry object.
    – If I can get this all to work, I may make this into a "simple" dice style battle game. but that is way off, I just want to get this nesting of objects to work with inheritance for now.

    Thanks in advance for any help you can provide.
    Here is a link to the "live" example. (not much different there except if you have firebug you can see the console.log method showing the objects, and how they are inheriting in properly from my POV.)

    http://tampa.dingledoodle.com/soldiers2/


    Blue

    Joe
    # December 22, 2011 at 5:36 am

    If you have done Object Oriented Programming in JavaScript, you will know that you can create a class as follows:

    Person = function(id, name, age){
    this.id = id;
    this.name = name;
    this.age = age;
    alert(‘A new person has been accepted’);
    }

    So far our class person only has two properties and we are going to give it some methods. A clean way of doing this is
    to use its ‘prototype’ object.
    Starting from JavaScript 1.1, the prototype object was introduced in JavaScript. This is a built in object that
    simplifies the process of adding custom properties and methods to all instances of an object.
    Let’s add 2 methods to our class using its ‘prototype’ object as follows:

    Person.prototype = {
    /** wake person up */
    wake_up: function() {
    alert(‘I am awake’);
    },

    /** retrieve person’s age */
    get_age: function() {
    return this.age;
    }
    }

    Now we have defined our class Person. What if we wanted to define another class called Manager which inherits some properties from Person. There is no point redefining all this properties again when we define our Manager class, we can just set it to inherit from the class Person.
    JavaScript doesn’t have built in inheritance but we can use a technique to implement inheritance as follows:

    `Inheritance_Manager = {};`//We create an inheritance manager class (the name is arbitrary)

    Now let’s give our inheritance class a method called extend which takes the baseClass and subClassas arguments.
    Within the extend method, we will create an inner class called inheritance function inheritance() { }. The reason why we are using this inner
    class is to avoid confusion between the baseClass and subClass prototypes.
    Next we make the prototype of our inheritance class point to the baseClass prototype as with the following code:
    inheritance.prototype = baseClass. prototype;
    Then we copy the inheritance prototype into the subClass prototype as follows: subClass.prototype = new inheritance();
    The next thing is to specify the constructor for our subClass as follows: subClass.prototype.constructor = subClass;
    Once finished with our subClass prototyping, we can specify the next two lines of code to set some base class pointers.

    subClass.baseConstructor = baseClass;
    subClass.superClass = baseClass.prototype;

    Here is the full code for our extend function:

    Inheritance_Manager.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;
    }

    Now that we have implemented our inheritance, we can start using it to extend our classes. In this case we are going to
    extend our Person class into a Manager class as follows:

    We define the Manager class

    Manager = function(id, name, age, salary) {
    Person.baseConstructor.call(this, id, name, age);
    this.salary = salary;
    alert(‘A manager has been registered.’);
    }

    we make it inherit form Person

    Inheritance_Manager.extend(Manager, Person);

    If you noticed, we have just called the extend method of our Inheritance_Manager class and passed the subClass Manager in our case and then the baseClass Person. Note that the order is very important here. If you swap them, the inheritance
    will not work as you intended if at all.
    Also note that you will need to specify this inheritance before you can actually define our subClass.
    Now let us define our subClass:

    We can add more methods as the one below. Our Manager class will always have the methods and properties defined in the Person class because it inherits from it.

    Manager.prototype.lead = function(){
    alert(‘I am a good leader’);
    }

    Now to test it let us create two objects, one from the class Person and one from the inherited class Manager:

    var p = new Person(1, ‘Joe Tester’, 26);
    var pm = new Manager(1, ‘Joe Tester’, 26, ‘20.000’);

    Feel free to get full code and more comments at:
    http://www.cyberminds.co.uk/blog/articles/how-to-implement-javascript-inheritance.aspx

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.

*May or may not contain any actual "CSS" or "Tricks".