Показать сообщение отдельно
  #1 (permalink)  
Старый 01.09.2012, 02:13
Аватар для FINoM
Новичок
Отправить личное сообщение для FINoM Посмотреть профиль Найти все сообщения от FINoM
 
Регистрация: 05.09.2010
Сообщений: 2,298

Немного магический способ наследования
Не люблю использовать всякие обертки, типа
Constr = Constructor( Parent, function() {});

Не нравится и то, что во многих реализациях наследования, функция, отвечающая за него пишется под конструктором:
Constr = function() {
  // ...много кода
}

inherit( Constr, Parent );


Из-за этого приходится скроллить вниз, дабы посмотреть, наследует ли конструктор свойства другого конструктора.

Хотелось бы использовать обычные, традиционные функции-конструкторы, но с кратким и очевидным наследованием, определенным в начале функции:
Constr = function() {
  inherit( this, Parent );
 // ... много кода
}

Мне кажется это красивым и удобным (а используя defineProperty можно добиться еще большей лаконичности и писать this.inherit( Parent )).

Немного магии:
var inherit = function( object, Parent ) {
	var args = Array.prototype.slice.call( arguments, 2 ),
		proto = object.__proto__;
		
	Parent.apply( object, args );
	
	if( proto.__proto__.constructor !== Parent ) { 
		proto.__proto__ = applyConstruct( Parent, args );
	}
}

var applyConstruct = function( Constructor, args ) {
	var argNames = [];
	for( var i = 0; i < args.length; i++ ) {
		argNames.push( 'arg' + i );
	}
	argNames.join( ',' );
	
	return new Function( argNames, 'return new this( ' + argNames + ' );' ).apply( Constructor, args );
}

C1 = function C1() {
	this.a = 1;
	this.b = 12;
};

C1.prototype = {
	m1: function() {
		// 11
	},
	m2: function() {
		// 12
	}
};

C2 = function C2() {
	inherit( this, C1 );
	this.b = 22;
	this.c = 23;
};

C2.prototype = {
	m2: function() {
		// 22
	},
	m3: function() {
		// 23
	}
};
C3 = function C3() {
	inherit( this, C2 );
	this.c = 33;
	this.d = 4;
};

C3.prototype = {
	m3: function() {
		// 33
	},
	m4: function() {
		// 34
	}
};


Здесь используется свойство __proto__, которое не поддерживается даже новыми ИЕ. В дальнейшем постараюсь избавиться от этого свойства, но появится небольшая избыточность:

Constr = function() {
  inherit( this, Constr, Parent );
 // ... много кода
}


Хотя еще не представляю, как добиться этого. В этой теме Почему не работает код? Вопрос о this.constructor. было выяснено, что prototype нельзя переопределить после инициализации экземпляра конструктора.
__________________
"Matreshka is fucking awesome" © чувак с Reddit
Matreshka.js - Три возможности

Последний раз редактировалось FINoM, 01.09.2012 в 02:19.
Ответить с цитированием