LINUX.ORG.RU

Наследование в яваскрипте


0

1

Пытаюсь освоить наследование, а именно сделать:
1. Объект Model, в котором есть (например) методы Save() и Remove()
2. Объект ModelUser, который наследуется от Model и в котором есть (например) Check().
3. Реальный юзер взятый из БД, у которого прототип равен ModelUser.prototype

Как делаю:

function Models(site)
{
	this.site=site;
	return this;
}

Models.prototype.model_name=function(model)
{
	var arr=model.toString().match(/^function Model(\w+)/);
	return arr[1].toLowerCase();
}

Models.prototype.list=function(model,rule)
{
	
}

Models.prototype.get_by_pk=function(model,pk)
{
	var r=this.site.sql.execute_and_fetch_one("_models/"+this.model_name(model)+"/get",{id:pk});
	r.prototype=model.prototype;
	return r;
}

function Model()
{
	throw("Model");
}

Model.prototype.Save=function() {
	throw("Model.prototype.save");
}

Model.prototype.Remove=function() {
	return 1;
}

function ModelUser() {
	return this;
}

ModelUser.prototype.prototype=Model.prototype;

ModelUser.prototype.Check=function () {
	return 1;
}

function models_test(space)
{
	models=new Models(space.site)
	var u1=models.get(ModelUser,1);
	if (u1.Check()!=1) throw("u1.Check!");
	if (u1.Remove()!=1) throw("u1.Remove!");
}
Ругань имею следующую:
{
	message: "Object # has no method 'Check'"
	stack: "TypeError: Object # has no method 'Check'
    at models_test (/home/projects/oneworldcms/code/models/generic2.js:64:9)
    at Object.models_test (/home/projects/oneworldcms/code/models/generic2.js:71:3)
    at OneWorldCmsServer.processPage (/home/projects/oneworldcms/code/server/server.js:239:68)
    at OneWorldCmsServer.iterate (/home/projects/oneworldcms/code/server/server.js:163:12)
    at OneWorldCmsServer.work (/home/projects/oneworldcms/code/server/server.js:113:13)
    at Object. (/home/projects/oneworldcms/app.js:8:5)"
	type: "undefined_method"
	arguments:  [
		"Check"
		{
			id: "1"
			login: "admin"
			first_name: null
			second_name: null
			last_name: null
			calc_full_name: null
			password: ""
			enabled: "1"
			email: null
			no_roles: "0"
			sex_id: null
			date_cr: "2010-12-12 20:35:51.604354"
			date_birth: null
			im_icq: null
			im_jabber: null
			im_msn: null
			im_skype: null
			phone: null
			date_last_page: null
			prototype: {
				prototype: ...
				Check: ...
			}
		}
	]
	name: "TypeError"
}

что я делаю не так?

★★★

Последнее исправление: vahvarh (всего исправлений: 1)

Ответ на: комментарий от geekless

models.get() - я просто удалил, оно не содержательное, просто вызывает this.get_by_pk().

r.prototype=model.prototype;

Это что за ересь?

Вот именно эта ересь меня и интересует. Как это сделать правильно?

vahvarh ★★★
() автор топика
Ответ на: комментарий от vahvarh

>Вот именно эта ересь меня и интересует. Как это сделать правильно

Вы не понимаете, как устроено прототипное наследование в JS. Вызов new() порождает новый объект и задаёт его свойство constructor. Вызов «прототипных» методов объекта производится через объект.constructor.prototype. Вы же пытаетесь заначить прототип уже сформированному объекту. Присваивание полю объект.prototype бессмыленно.

geekless ★★
()
function __extend(child, parent)
{
    var tmp = function(){};
    tmp.prototype = parent.prototype;
    child.prototype = new tmp();
    child.prototype.constructor = child;
}

Только обхода свойств не хватает

Bad_Habit
()

Лучшее наследование не нативно прототипами а копированием методов. Потому что обход цепочки прототипов это O(n) где n длинна цепочки.

bga_ ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.