将对象与模块模式组合时,我做错了什么

时间:2014-01-14 10:58:24

标签: javascript function object iife

Possible duplicate对我没有帮助,因为类似的问题,我在面试中失败了。

我们的想法是使用Objectmodule pattern创建一个人inheritance,他是管理员的老师和祖父的父亲。 类似于经理 - >老师 - >人

我的代码看起来像那样(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;
    });


})(); 

我在第一行收到错误:

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

错误是:Uncaught TypeError: object is not a function

有人可以帮助我吗?我也愿意听到对此代码的其他改进。

3 个答案:

答案 0 :(得分:3)

这是您创建(和调用)self-executing function or IIFE的方式:

(function () {})();

简单地写(function () {})不会调用函数,在这种情况下它实际上没有实际效果。按照您的方式APP.Person将是一个函数,返回另一个函数(Person的构造函数)调用时 - 它将无法与new一起运行。< / p>

此外,对于documentready,您不希望执行.ready调用的结果,只需将function作为参数传递,它将在事件触发时被调用:

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

Plunk with these changes

答案 1 :(得分:1)

所有对象都声明如下:

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

这本身并没有错,虽然有点奇怪。你想要的是:

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

然后,你为什么要打扰IIFE呢?您也可以这样做:

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

封装它们绝对没有任何意义,没有任何私有你从外部范围隐藏。


此外,我的帖子可能比StackOverflow更适合CodeReview,但您的继承模型存在重大问题。您的Teacher.prototype是没有参数创建的Person实例。只有在高度限制的情况下,这才是安全的。

一个更好的模型就是这个:

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

关于这个特定问题的SO有许多好的答案,here是我的一个。

答案 2 :(得分:0)

不需要jQuery来创建这些东西。好吧,我对此并没有很好的曝光,但我试图展示你想知道的事情:

// 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

所以,上面你可以看到: - 使用2个属性和一个方法创建Person类。 - 然后我们创建了一个Teacher类,并继承了Person类中的方法。 - 然后在其中添加了另一个名为getFullDetails()的方法,该方法访问来自Person类的方法。

这就是你在DOM.ready中所做的事情:

alert(x.getInfo()); // in my 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());