This Possible duplicate did not help me, I failed on an interview because of a similar question.

The idea is to create a person Object that is a father of teacher and grandfather of Manager using module pattern and inheritance. Something like that Manager->Teacher->Person

My code looks like that(My Plunk):

(function(undef)
{
    /**Waiting till document is ready before applying next functions*/
    $(document).ready(function(){

        var person = new APP.Person('Aria Stark','223232');
        document.write(person.getDetails());
    })();

     var APP = {};

     APP.Person =(function() {

        function Person(name, ID) {
            this.name = name;
            this.ID = ID;
        }

        Person.prototype.getDetails = function() {
            return " name: " + this.name + " ID: " + this.ID;
        };

        return Person;
    });

    APP.Teacher =(function () {

        function Teacher(name, ID, salary, hatColor) {
            APP.Person.call(this, name, ID);
            this.salary = salary;
            this.hatColor = hatColor;
        }

        Teacher.prototype = new APP.Person();

        Teacher.prototype.getDetails = function() {
            return APP.Person.call(this) + " Salary: " + this.salary + " Hat: " + this.hatColor;
        };

        return Teacher;
    });


    APP.Manager =(function () {

        function Manager(name, ID, salary, hatColor, car) {
            APP.Teacher.call(this, name, ID, salary, hatColor);
            this.car = car;
        }

        Manager.prototype = new APP.Teacher();

        Manager.prototype.getDetails = function() {
            return APP.Teacher.call(this) + " Car: " + this.car;
        };

        return Manager;
    });


})(); 

I get an error on the first line:

var person = new APP.Person('Aria Stark','22323');

The error is: Uncaught TypeError: object is not a function

Can someone help me with with that? I'm also open to hear other improvements to this code.

有帮助吗?

解决方案

This is how you create (and call) a self-executing function or IIFE:

(function () {})();

Simply writing (function () {}) does not call the function, it actually has no real effect in this case. With your way APP.Person will be a function, that returns another function (the constructor for Person) when called - it will not operate well with new.

Also, for the documentready, you don't want to execute the result of the .ready call, just pass the function as a parameter, it will be called when the event triggers:

$(document).ready(function(){
}); //removed () from here

Plunk with these changes

其他提示

All your objects are declared like this:

APP.X=(function() {
    function Y() {}
    Y.prototype.method= function() {};
    return Y;
});

That is not wrong in itself, though it is a bit odd. What you want to have is this:

APP.X=(function() {
    function X() {}
    X.prototype.method= function() {};
    return X;
})(); // actually call the anonymous function you used to encapsulate variables

Then again, why do you bother with an IIFE? You might just as well do this:

APP.X = function () {}
X.prototype.method= function() {};

Encapsulating them brings absolutely nothing, there is nothing private you are hiding from the outer scope.


Also, my post might be better suited for CodeReview than StackOverflow, but your inheritance model has significant issues. Your Teacher.prototype is an instance of Person created with no parameters. Only under highly restrictive circumstances will that be safe.

A better model would be this one:

Teacher = function(){
    Person.call(this /*, person parameters*/);
}
Teacher.prototype = Object.create(Person.prototype);

There are many good answers on SO dealing with this specific issue, here is one from me.

There is no need of jQuery to create these things. Well, I have not very good exposer on this, but I tried to show the things you want to know:

// Creating Person Class
var Person = function(name, id){
    this.name = name;
    this.id = id;
};

Person.prototype.getInfo = function(){
    return "name: " + this.name + ",  id: " + this.id;
};

// Instance of Person
var x = new Person("Ashish", 1);
x.getInfo();

// Creating Teacher Class
var Teacher = function(name, id, salary, hatColor){
    Person.call(this, name, id);
    this.salary = salary;
    this.hatColor = hatColor;
};

// Inheriting Persons methods
Teacher.prototype = new Person();

// Adding new method to it
Teacher.prototype.getFullDetails = function(){
    return this.getInfo() + ", salary: " + this.salary + ", Hatcolor: " + this.hatColor;
}

// Instance of Teacher Class
var teacher = new Teacher("John", 2, 15000, "red");
teacher.getInfo(); //output: "name: John,  id: 2"
teacher.getFullDetails(); // output : "name: John,  id: 2, salary: 15000, Hatcolor: red"
console.log(teacher.salary); // output : 15000

So, above you can see: - A Person class is created with 2 properties and one method. - and then we created a Teacher class and inherited the method from Person class in it. - and then added another method called getFullDetails() in it which accesses the method coming from Person class.

And this is what you are doing in the DOM.ready:

alert(x.getInfo()); // in my example:

In your example:

var APP = {};
APP.Person = function Person(name, ID) {
    this.name = name;
    this.ID = ID;
}

APP.Person.prototype.getDetails = function () {
    return " name: " + this.name + " ID: " + this.ID;
};

var person = new APP.Person('Aria Stark', '223232');
alert(person.getDetails());
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top