Pull to refresh

Наследование без Prototype

Reading time 2 min
Views 4.5K
В JavaScript наследование сделано через Prototype. Почему же не сделать наследование не через него, нигде не написано. Программисту, который больше всего пишет на PHP или любом другом языке, где «Прототип», это порождающий шаблон проектирования, а не способ наследования в JavaScript, очень трудно взять и начать писать классы, поэтому их почти никто собственно и не пишет на своих сайтах, а только в каких либо изощренных задачах или в специальных библиотеках.

Большая часть сайтов обходится без классов. Максимум на что можно рассчитывать, это использование какого-либо JavaScript фреймворка, где можно надеется, что это присутствует.

Мучаясь бездельем, как уже многие до меня, я попробовал реализовать классы без прототипа. И собственно говоря что-то получилось, ну а что получилось, я вам и собственно и расскажу. Пытаясь найти хоть какие-то преимущества данного способа, я увидел, что можно наследоваться в каком угодно порядке от любого количества классов.

Что такое класс? Тип объекта. А задать тип объекта можно без prototype. Как сделать ссылки на родителей? Первое, что пришло в голову, это скопировать все его методы и переменные. Наверняка пострадает производительность.

function Class(name, b, c) {

	window[name] = function(){
		/* Добавляем члены класса */
		for(var v in c) {
			if (!c.hasOwnProperty(v)) this[v] = c[v];
		}

		
		/* Делаем наследование */
		this.__bases = [];
		for(var i = 0; i < b.length; i++) {
			this.__bases.push([]);
			for (var v in b[i].__dict)	{
				if (!c.hasOwnProperty(v) && v != 'construct') {
					this[v] = b[i].__dict[v];
                                }
				else
				{
					this.__bases[i][v] = function(obj, f) {
						if (typeof f == 'function') {
							return function() {							
								f.apply(obj, arguments)
							};
                                                } else {
							return f;
						}
					}(this, b[i].__dict[v]);	
				}
                        }			
		}

		/* Вызываем конструктор */
		if (c.hasOwnProperty('construct')) {
			c['construct'].apply(this, arguments);
		}
		else
		{
			for(var i = 0; i < b.length; i++) {
				if (b[i].__dict.hasOwnProperty('construct')) {
					b[i].__dict['construct'].apply(this, arguments);
				}
		        }
		}
	};

        window[name].__dict = c;
}


В MooTools с точки зрения синтаксиса лучше всего сделаны классы, у меня получилось нечто похожее

Class('Person', [], {
    age: 0,
    name: '',

    construct: function(name, age) {
 	this.name = name;
        this.age = age;
    },

    who : function(){
       return this.name + ' ' + this.age;
    }
});

var v = new Person('Vova', 25);
var w = new Person('Pavlik', 23);

alert(w.who());
alert(v.who());


Наследование идет слева направо и не может быть вложенным. Если конструктора нет в дочернем классе, вызывается все конструкторы родительских по очереди слева направо. Вызов родительских методов можно реализовать через переменную __bases:

Class('Student', [Person], {
    subjects: [],

    construct: function(name, age, subjects) {
        this.__bases[0].construct(name, age);
 	this.subjects = subjects;
    },

    who : function(){
        return 'Student '+ this.name + ' ' + this.age + ' ' + this.subjects.join(', ');
    }
});

var v = new Student('Vova', 25, ['Maths', 'History']);
alert(v.who());



На этом я свои изыскания закончил. Хочу выслушать мнения по данному способу создавать объекты. В чем по вашему минусы данного подхода?
Tags:
Hubs:
-29
Comments 33
Comments Comments 33

Articles