2011-12-21 3 views
2

В этом примере я пытаюсь создать шаблон класса, а затем использовать его для создания базового класса и т. Д. И т. Д.Как я могу исправить этот пример, чтобы он работал после первого или второго подкласса?

Все работает, пока я не доберусь до NewStudent. Я получаю объект типа «объект не является функцией».

var Class = function(options) { 
    var newClass = function(options) { 
     $.extend(this, options); 
    }; 

    if (options) { 
     $.extend(newClass, options); 
    } 

    newClass.prototype = newClass; 
    newClass.prototype.constructor = newClass; 
    return newClass; 
}; 

var Person = new Class(); 
Person.prototype.speak = function() {alert(this.name + ', ' + this.type);} 


var Student = new Person({name: 'Student', type: 'Student'}); 
Student.speak(); 

var NewStudent = new Student({name: 'NewStudent'}); 
NewStudent.speak(); 

Если я изменю:

var newClass = function(options) { 
    $.extend(this, options); 
}; 

к:

var newClass = function(options) { 
    $.extend(this, options); 
    return newClass; 
}; 

Это он выполняет вызов говорить, но имя пустое, и тип неопознанный.

Я использую jquery для метода $ .extend.

Как я могу улучшить это, чтобы он работал? Я пытаюсь сделать что-то похожее на то, как Mootools выполняет свой класс, за исключением того, что я хочу создать свою собственную barebone-версию.

ответ

2

Вы путаете объекты с функциями.

Переменная Person является функцией, но переменная Student является обычным объектом, поэтому вы не можете ее «обновить».

Вам понадобится создать отдельную функцию для создания производных классов. Я переработал ваш пример немного, и пришел с этим:

Class = function(ParentClass, options) { 

    if (ParentClass && typeof(ParentClass) != 'function') { 
     options = ParentClass; 
     ParentClass = undefined; 
    } 

    var ctr = function(objOptions) { 
     $.extend(this,objOptions); 
    }; 

    if (typeof(ParentClass) == 'function') { 
     ctr.prototype = new ParentClass(); 
    } 

    $.extend(ctr.prototype,options); 

    ctr.Derive = function(options) { return new Class(ctr,options); }; 

    return ctr; 
}; 

Тогда вы можете делать то, что вы хотели:

var Person = new Class({ speak: function() {alert(this.name + ', ' + this.type);} }); 
var Student = Person.Derive({type: 'Student'}); 
var NewStudent = Student.Derive({type:"NewStudent"}); 

var student = new Student({name: 'student'}); 
student.speak(); 

var newStudent = new NewStudent({name: 'newStudent'}); 
newStudent.speak(); 

Код выше может быть выполнен здесь: http://jsbin.com/unetox/6

+0

Так вызывая новый на функцию возвращает объект. Я попытаюсь автоматизировать его еще один уровень, чтобы избежать вызова Class.create (если это возможно). Спасибо за вашу помощь! – user1110412

+0

Вы не можете ожидать, что «новый Student()» создаст для вас новый класс и в то же время позволит вам создать новый объект типа «Student». Я не думаю, что вы можете сделать это намного проще, чем то, что я показал. –

+0

Я сделал небольшое изменение, упрощающее его использование. –

Смежные вопросы