Показать сообщение отдельно
  #7 (permalink)  
Старый 08.05.2011, 03:57
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Lerayne, у тебя 2 ошибки:
1. ты перезаписываешь все свойство prototype новым объектом (стр. 43, 54). В старом содержались всякие Function#apply и Function#call , а в новом их нет. Нужно просто дописывать новые методы в уже существующий объект.
2. функция extend тоже перезаписывает весь prototype, но делает это грамотно - новый объект содержит все нужные методы (наследует их от Function). Таким образом, ты сначала добавляешь новый метод, а затем в extend он затирается вместе со всем prototype. Поэтому нет доступа к func. Нужно сперва вызывать extend, а затем добавлять новые методы.

Поправил твой пример:
function extend(Parent, Child) {
    var F = function() { }
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype;
}

// функция создания дива с классом и содержимым
function div(className, content){
    var elem = document.createElement('DIV');
    if (className) elem.className = className;
    if (content) elem.innerHTML = content;
    return elem;
}

// вариант 2, все свойства и методы добавляются через прототип:
 
function P(color){
    this.populate(color);
}
P.prototype.populate = function(color){
	this.container = div('container', 'empty');
	this.container.style.background = color;
};

function C(color){
    this.populate(color);
    this.func();
}
extend(P, C);
C.prototype.func = function(){
	this.header = div('header', 'Заголовок!');
	this.container.appendChild(this.header);
};

function GC(color){
    this.populate(color);
    if (this.func) this.func();
     
    this.message = div('messge', 'Сообщение!');
    this.container.appendChild(this.message);
}
extend(C, GC);

window.onload = function() {
	document.body.appendChild(new P('#FF7777').container); // выводит только "empty"
	document.body.appendChild(new C('#FF9999').container); // выводит "empty" и "Заголовок!"
	document.body.appendChild(new GC('#FFbbbb').container); // "empty", "Заголовок!" и "Сообщение!"
};


Что бы не делать таких ошибок, можно использовать небольшой конструктор классов. У меня бы получилось так:

var $extend = Object.extend = function(self, obj) {
	if (self == null) self = {};
	for (var key in obj) self[key] = obj[key];
	return self;
}

var Class = {
	create: function(parent, declaration) {
		function klass() {
			this.initialize.apply(this, arguments);
		}
		if (typeof parent == 'function') {
			function F() {}
			F.prototype = parent.prototype;
			klass.prototype = new F();
		} else {
			if (parent != null) declaration = parent;
			parent = Object;
		}
		$extend(klass.prototype, declaration).initialize || (klass.prototype.initialize = Function.blank);
		klass.$super = parent;
		klass.prototype.$super = parent.prototype;
		return klass.prototype.constructor = klass;
	}
};

function div(className, content) {
    var elem = document.createElement('DIV');
    if (className) elem.className = className;
    if (content) elem.innerHTML = content;
    return elem;
}

var P = Class.create({
	initialize: function(color) {
		this.populate(color);
	},

	populate: function(color) {
		this.container = div('container', 'empty');
		this.container.style.background = color;
	}
});

var C = Class.create(P, {
	populate: function(color) {
		P.prototype.populate.call(this, color);
		this.header = div('header', 'Заголовок!');
		this.container.appendChild(this.header);
	}
});

var GC = Class.create(C, {
	populate: function(color) {
		C.prototype.populate.call(this, color);
		this.message = div('messge', 'Сообщение!');
		this.container.appendChild(this.message);
	}
});

window.onload = function() {
	document.body.appendChild(new P('#FF7777').container); // выводит только "empty"
	document.body.appendChild(new C('#FF9999').container); // выводит "empty" и "Заголовок!"
	document.body.appendChild(new GC('#FFbbbb').container); // "empty", "Заголовок!" и "Сообщение!"
};


Сообщение от Kolyaj
Здесь не создаётся экземпляр родительского класса, а просто вызывается его конструктор в контексте текущего this
все равно плохо.

Последний раз редактировалось Riim, 08.05.2011 в 04:05.
Ответить с цитированием