0

i have made two classes, which is person - the parent class and a student class - the child class. i am trying to implement inheritance. also i am trying to implement it in modular pattern. but its not getting properly. for the code block please check below.

Person.js

var Person = function() {

    var details, constructor, getDetailsByAttribute, setDetailsByAttribute, setDetails, getDetails, clearDetails;

    clearDetails = function()   {
        details = {
            uid : '',
            name : '',
            email : ''
        };
    };

    getDetailsByAttribute = function(attr)  {
        return details[attr];
    };

    setDetailsByAttribute = function(key, value)    {
        if(details.hasOwnProperty(key)) {
            details[key] = value;
        }else   {
            console.log('invalid key');
        }
    };

    setDetails = function(param)    {
        clearDetails();
        for(var attr in param)  {
            if(details.hasOwnProperty(attr))    {
                details[attr] = param[attr];
            }
        }
    };

    getDetails = function() {
        return details;
    };

    /**
     * During object creation;
     */
    if(arguments.length >= 1)   {
        //clearDetails();
        setDetails(arguments[0]);
    }

    return {
        getDetailsByAttribute : function(attr)  {
            return getDetailsByAttribute(attr);
        },

        setDetailsByAttribute : function(key, value)    {
            setDetailsByAttribute(key, value);
        },

        setDetails : function(params)   {
            setDetails(params);
        },

        getDetails : function() {
            return getDetails();
        },

        clearDetails : function()   {
            clearDetails();
        }
    };
};

Student.js

var Student = function()    {
    Person.call(this,arguments);
};

Student.prototype = new Person();

index.html

<html>
    <head>
    </head>
    <body>
        <script type="text/javascript" src="modules/Person.js"></script>
        <script type="text/javascript" src="modules/Student.js"></script>
        <script type="text/javascript">
            var person1, person2, person3, student1;

            person1 = new Person({
                uid : 5225,
                name : 'jaison',
                email : 'jaison@jaison.com'
            });

            person2 = new Person({
                uid : 5222,
                name : 'jatin',
                email : 'jatin@jatin.com'
            });

            person3 = new Person();
            person3.setDetails({
                uid : 5221,
                name : 'sarath',
                email : 'sarath@sarath.com'
            });
            person3.setDetailsByAttribute('name', 'sarath');

            student1 = new Student({
                uid : 5221,
                name : 'sachin',
                email : 'sachin@sachin.com'
            });

            console.log('person 1 : ',person1.getDetails());
            console.log('person 2 : ',person2.getDetails());
            console.log('person 3 : ',person3.getDetails());
            console.log('student 1 : ',student1.getDetails());
            //console.log(student1.get);

        </script>
    </body>
</html>
Jaison Justus
  • 2,753
  • 8
  • 47
  • 65
  • possible duplicate of [How to get a constructor function to inherit from a constructor function in Javascript?](http://stackoverflow.com/questions/2263353/how-to-get-a-constructor-function-to-inherit-from-a-constructor-function-in-java) – outis Jun 06 '12 at 08:49
  • 2
    An anonymous function that simply calls another function (such as you use in the object literal returned by the `Person` constructor) is completely unnecessary. Simply use the function. `{getDetailsByAttribute: getDetailsByAttribute, ...}` is perfectly legal and works correctly, as an object's properties are a separate namespace from other object properties and local variables. – outis Jun 06 '12 at 08:51
  • thanks for the valuable point. but with referenced to the above question you commented, i change the code a little but still not working. – Jaison Justus Jun 06 '12 at 09:03
  • Also you can use this `{... setDetailsByAttribute: setDetailsByAttribute, ... }` – jcubic Jun 06 '12 at 13:11

2 Answers2

2

try this:

var Student = function()    {
    return Person.apply(this, arguments);
};

without

Student.prototype = new Person();

UPDATE: I just realize that you can use this:

var Student = function()    {
    this.setDetails.apply(this, arguments);
};
Student.prototype = new Person();

So the closure will be inside prototype, and setDetails will access it.

In your code when you do this:

Student.prototype = new Person();

you create a closure and when You call this

var Student = function()    {
    Person.call(this,arguments);
};

you create another closure (and it should not be call but apply, but even that it will not work). you execute constructor as a function and (if it will be apply it will) apply arguments to different closure, and all those functions that are returned by Person with detail inside the closure will be discard. methods of Student will be taken from prototype not from constructor.

jcubic
  • 61,973
  • 54
  • 229
  • 402
  • but hows its possible if student module return a set of functions like return { foo : foo, bar : bar, test : testing }.. – Jaison Justus Jun 06 '12 at 11:38
  • So you return them back on Child class (function). Take a look how you had written Person, it's not a class it's a function (that return an object) you didn't use `this`. so It will work even if you do `student1 = Student({...});` without `new`. You can't use inheritence in your code because you use closures and functional programming not object oriented programming. What you where looking for is `super` function but JavaScript don't have one. – jcubic Jun 06 '12 at 11:48
  • thats for the info pal. do you know any place to learn javascript oops. good one. – Jaison Justus Jun 06 '12 at 12:06
  • 1
    @JaisonJustus You can check this https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript I'm Not sure I understand what you mean by 'modular pattern'. – jcubic Jun 06 '12 at 13:11
1

The problem is that details is a local variable in prototype and a local variable in Person.apply call. These are different. My advice is to attach details to the object, i.e.

var Person = function() {
    var self = this;
    self.details = null;

    // the other code goes here;

    clearDetails = function()   {
        self.details = {
            uid : '',
            name : '',
            email : ''
        };
    };

    setDetails = function(param)    {
        clearDetails();
        for(var attr in param)  {
            if(self.details.hasOwnProperty(attr))    {
                self.details[attr] = param[attr];
            }
        }
    };

    // and the other code here.
}

Bascially change details to self.details everywhere. I didn't test it, but it should work.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • @freakinsh if we add this.details in side the function does its scope remains private or public – Jaison Justus Jun 06 '12 at 11:30
  • 1
    @JaisonJustus Generally there is no such thing as private/public scope *sensu stricto* in JavaScript. But in some sense this is no longer "private" scope, i.e. `details` can be easily seen outside of the object. – freakish Jun 06 '12 at 13:10
  • thank you pal. its was my misunderstanding about private/public oops.. :) – Jaison Justus Jun 06 '12 at 13:17