ООП в JavaScript

    Хочу представить вам функцию-конструктор классов createClass.
    Чем хорош этот конструктор:
    1. Сам код выглядит более читабельным и понятным
    2. Поддержка множественного наследования
    3. Поддержка абстрактных методов
    4. Наследование статических методов и свойств класса
    5. Умный метод instanceOf (проверяет по всей цепочке классов)

    Итак, сразу пример:
    var Animal = createClass({
    	abstracts: ['say'],
    	construct: function(name) {
    		this.name = name;
    	},
    	eat: function() {
    		return 'ou yeah...';
    	}
    });
    
    var Kitty = createClass({
    	extend: Animal,
    	say: function() {
    		return this.name + ' said: RrrrRRR...Mau..';
    	},
    	eat: function() {
    		return Animal.fn.eat.call(this) + 'FISH!!'
    	}
    });
    
    var Doggy = createClass({
    	extend: Animal,
    	construct: function(name) {
    		Animal.call(this, name);
    		console.log('doggy have been created');
    	},
    	say: function() {
    		return this.name + ' said: GAV!';
    	},
    	eat: function() {
    		return Animal.fn.eat.call(this) + 'MEAT!!'
    	}
    });
    
    var sharik = new Doggy('sharik'); // doggy have been created
    var murka = new Kitty('murka');
    
    console.log( sharik.eat(), sharik.say()); // ou yeah...MEAT!! sharik said: GAV!
    console.log( murka.eat(), murka.say()); // ou yeah...FISH!! murka said: RrrrRRR...Mau..
    

    Все свойства класса должны определяться в конструкторе (статические свойства в статическом конструкторе, о нём речь пойдёт ниже).
    Класс Animal имеет обстрактый метод “say”. Классы Kitty и Doggy наследуется от Animal и реализуют метод “say”. При этом, поскольку в Kitty конструктор явно не задан, он заимствуется у Animal. В Doggy конструктор задан явно, поэтому родительский конструктор нужно вызвать тоже явно Animal.call(this, name). Метод eat родительского класса можно вызвать как Animal.fn.eat.call(this) это тоже самое, что Animal.prototype.eat.call(this)

    Дальше:
    var Singleton = createClass({
    	statics: {
    		construct: function() {
    			this._instance = null;
    		},
    		getInstance: function() {
    			if(this._instance === null) {
    				this._instance = new this();
    			}
    			return this._instance;
    		}
    	}
    });
    
    var SuperDoggy = createClass({
    	extend: [Animal, Singleton],
    	say: function() {
    		return this.name + ' said: GAV! GAV! GAV!';
    	}
    });
    
    var dog1 = SuperDoggy.getInstance(),
    dog2 = SuperDoggy.getInstance();
    
    dog1.name = 'Bob';
    
    console.log(dog1 === dog2); // true
    console.log(dog1.eat(), dog1.say()); // ou yeah... Bob said: GAV! GAV! GAV!
    

    Singleton имеет статическое свойство _instance и статический метод getInstance. Этот класс может применяться в качестве реализации паттерна Singleton. SuperDoggy наследуется от двух классов Animal, Singleton и реализует метод “say”.
    Стоит отдельно отметить метод construct в обьекте statics. Этот метод вызывается при создании самого класса и при создании класса-наследника. Он позволяет корректно копировать при наследовании статические свойства объекта. Если в объекте prototype есть метод constructor, который создаёт объект, то почему бы не иметь constructor, создающий сам класс?

    Примеры применения метода “instanceOf”:
    console.log( dog2.instanceOf(Kitty) === false ); // true
    console.log( dog2.instanceOf(SuperDoggy) === true );  // true
    console.log( dog2.instanceOf(Animal) === true ); // true
    console.log( sharik.instanceOf(Animal, Singleton) === false ); // true
    console.log( dog2.instanceOf(Animal, Singleton) === true ); // true
    

    Изначально идея была взята из книги Девида Фленагана JavaScript 5 издание: пример из книги. В итоге этот код эволюционировал в представленный в статье.

    Поскольку исходник не так велик, публикую его прямо тут:
    function createClass(data)
    {
    	var abstracts = data.abstracts || [],
    	statics = data.statics || {},
    	extend = data.extend || [];
    
    	if(!(extend instanceof Array))
    		extend  = [extend];
    
    	// define constructor
    	var constructor;
    	if(data.construct) {
    		constructor = data.construct;
    	} else if(extend.length) {
    		constructor = function() {
    			for(var i=0; i<extend.length; i++) {
    				extend[i].apply(this, arguments);
    			}
    		}
    	} else {
    		constructor = function() {};
    	}
    
    	// prototype for our class.
    	var proto = {};
    
    	delete data.construct;
    	delete data.abstracts;
    	delete data.statics;
    	delete data.extend;
    
    
    	// borrow methods from parent classes
    	for(var i=0; i<extend.length; i++) {
    		var parent = extend[i];
    
    		// static constructor
    		if( typeof parent.construct == "function")
    			parent.construct.call(constructor);
    
    		// copy static methods
    		for(var p in parent) {
    			if (typeof parent[p] != "function" || p == "construct") // copy only functions
    				continue;
    			constructor[p] = parent[p];
    		}
    
    		// Copy prototype methods
    		for(var p in parent.prototype) {
    			if (typeof parent.prototype[p] != "function" || p == "constructor")
    				continue;
    			proto[p] = parent.prototype[p];
    		}
    	}
    
    	// build abstract static methods
    	if(statics.abstracts) {
    		for(var p=0; p<statics.abstracts.length; p++) {
    			proto[ statics.abstracts[p] ] = function() {
    				throw p + ' is static abstract method'
    			};
    		}
    	}
    
    	// build abstract prototype methods
    	for(var p=0; p<abstracts.length; p++) {
    		proto[ abstracts[p] ] = function() {
    			throw p + ' is abstract method'
    		};
    	}
    
    	// internal methods
    	proto.instanceOf = function(_class) {
    		if(arguments.length > 1) {
    			var res = true;
    			for(var i=0; i<arguments.length; i++)
    				res = res && this.instanceOf(arguments[i]);
    			return res;
    		}
    
    		if(constructor === _class)
    			return true;
    
    		for(var i=0; i<extend.length; i++) {
    			if( extend[i].prototype.instanceOf.call(this, _class) )
    				return true;
    		}
    
    		return _class === Object;
    	};
    
    	// rest of data are prototype methods
    	for(var p in data) {
    		if (typeof data[p] != "function") // copy only functions
    			continue;
    		proto[p] = data[p];
    	}
    
    	// static functions of class
    	for(var p in statics) {
    		if (typeof statics[p] != "function") // copy only functions
    			continue;
    		constructor[p] = statics[p];
    	}
    
    	// static constructor
    	if( typeof statics.construct == "function")
    		statics.construct.call(constructor);
    
    //	proto.constructor = constructor;
    	constructor.prototype = proto;
    	constructor.fn = proto; // short case
    
    	// Finally, return the constructor function
    	return constructor;
    }
    
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 84
    • +19
      Поздравляю, вы изобрели mootools
      • +3
        Не нашёл особого сходства. Вы второй пример разбирали?
        P.S. И почему все сразу приводят примеры про Animal? :)
          • 0
            В мутулсе точно так же класс создается хешем, некоторые элементы которого являются кейвордами и обозначают наследование (втч множественное), конструкторы, деструкторы итп. Мутулс вообще очень сильно расширяет ООП яваскрипта, которое там, между прочим, есть и без фреймворков.

            И Мутулс не один такой, ниже есть потрясающий комментарий.
          • 0
            Немного ИМХО про mootools.

            1. Implements во всех языках обозначает, что класс должен реализовывать некий интерфейс, интерфейс — не содержит в себе никакой логики. Мутулс же копирует свойства обьекта, а значит по сути расширяет обьект. Следовательно это Extends, а не Implements (если я всё правильно понял).

            2. Вызов родительского класса типа this.parent(age) — лишнее звено. Средствами языка такой вызов делается Animal.call(this, age)

            3. initialize — не нравится мне такое название конструктора. Вот почему везде это constructor (construct), а тут initialize?

            Правда, создание класса через new Class(...) мне понравилось. Возможно, я тоже так сделаю.
            И, конечно, это всё мелочи, на которые можно и не обращать внимания.
            • 0
              И как добавлять в мутулс статические свойства в обьект?
              После его создания типа Cat.staticPtop1 = 'sdf'?
              При этом new Class теряет целостность.
              • 0
                Я написал свой мутатор Static.
              • 0
                1, 3 — согласен, странно. Может быть они сделали это во избежание совпадения кейвордов в будущем, а может потому, что в яваскрипте прототипное наследование — чтобы не смешивать терминологию. Хотя если честно, мне всегда казалось Init более подходящим для конструктора названием.

                2. Зато так мы можем напрямую не указывать в нескольких местах кода от чего унаследован класс. Во большинстве ООПшных языков вызов parent есть, почему бы не добавить это и в жс.
            • +1
              Мне кажется, было-бы лучше примеры кода спрятать под
            • +1
              Эм… По-моему CoffeeScript выглядит лучше. ИМХО конечно же…
              • +3
                По моему CoffeeScript создали по прихоти рубистов и любому javascript прогеру его синтаксис совсем не удобен. Тогда уж я могу сказать «Давайте писать на Dart», или на другом языке транслируемом в js.

                Тут же обсуждается именно реализация на следования в js.
                • 0
                  Ну так по сути делает тоже самое. И я бы не сказал что синтаксис, который тут предлагают намного удобней CS.
                  • 0
                    CoffeeScript это скажем так вообще не js, это язык который создан по образу и подобию руби и который транслируется в js.
                    Если вы пишите на руби то может быть CoffeeScript для вас все, я для себя там ничего удобного не видел. По сути там далеко не тоже самое.

                    Также замечу тут предлагают не синтаксис а реализацию на javascript, не надо это путать, у Javascript один синтаксис.

                    • –1
                      Хм… я бы сказал что CS больше похож на Erlang, чем на руби. Вы не поверите но CoffeeScript это тоже реализация на JS.
                      • 0
                        Что вы вкладываете в эти слова? CoffeeScript — это язык со своим синтаксисом, который при компиляции выдает javascript код. Я об этом писал выше. во что я не должен поверить по вашему?
            • +14
              И почему каждому второму хочется самому реализовать «множественное наследование» в JavaScript? Зачем вам множественное наследование? Оно вам точно надо? В подавляющем большинстве случаев эта задача решается аггрегированием либо использованием mixin, что не уродует иерархию наследования. Посмотрите, как реализовано ООП в YUI3, вам полезнее будет для развития.
              • –3
                Использовать множественное наследование или нет решать разработчику. В Java и Python к примеру оно есть. Предположу, что, как и всегда, его нужно использовать с умом.
                С помощью моего конструктора вы можете легко использовать и классы-примеси, помещая их в extend. Так же можно и подобие интерфейса использовать(класс со всеми абстрактными методами).

                Код даёт возможность использования тех технологий, которые выберет для себя разработчик.
                • +4
                  > В Java

                  Вы имеете в виду наследование поведения?
                  • 0
                    Извиняюсь, про Java я прогнал.
                    Вот нашёл в wiki языки, поддерживающие множественное наследование:
                    Eiffel, C++, Dylan, Python, Perl
                  • 0
                    А без вашего конструктора это было недостижимо?
                    • 0
                      Конструктор createClass никакого нового функционала (кроме метода instanceOf) не навешивает. Естественно это значит, что всё достижимо и на чистом JS. Просто так удобнее.
                • +97
                  Каждый программист на javascript должен написать свою реализацию классов. ©

                  Dojo — dojotoolkit.org/reference-guide/dojo/declare.html#dojo-declare
                  Sencha (ExtJS) — www.rogerwilco.ru/2011/04/sencha-extjs.html
                  qooxdoo — qooxdoo.org/documentation/0.7/oo_feature_summary
                  MooTools — www.phpeveryday.com/articles/MooTools-Basic-Creating-Classes-MooTools-P919.html
                  Prototype — www.prototypejs.org/learn/class-inheritance
                  AtomJS — github.com/theshock/atomjs/blob/master/Docs/Class/Class.md
                  JSClass — jsclass.jcoglan.com/classes.html
                  code.google.com/p/jsclassextend/
                  github.com/jcoglan/js.class
                  Cobra — justin.harmonize.fm/index.php/2009/01/cobra-a-little-javascript-class-library/
                  github.com/JustinTulloss/cobra
                  The $class Library- www.uselesspickles.com/class_library/
                  Classy — classy.pocoo.org/
                  YUI 3 — www.yuiblog.com/blog/2010/01/06/inheritance-patterns-in-yui-3/
                  Coffee-Script — jashkenas.github.com/coffee-script/#classes
                  JavascriptClasses — code.google.com/p/javascript-classes/
                  AJS — amix.dk/blog/post/19038
                  jsFace — github.com/tannhu/jsface
                  JsOOP — jsoop.codeplex.com/
                  joot — code.google.com/p/joot/wiki/API
                  oopsjs — code.google.com/p/oopsjs/
                  Objs — github.com/tekool/objs/wiki
                  oorja — maxpert.github.com/oorja/
                  objx — code.google.com/p/objx/wiki/OClass
                  jsclassextend — code.google.com/p/jsclassextend/
                  prolificjs — code.google.com/p/prolificjs/wiki/OOP
                  objectize — code.google.com/p/objectize/

                  code.google.com/p/core-framework/wiki/Inheritance
                  code.google.com/p/sfjsoo/
                  code.google.com/p/jslproject/
                  code.google.com/p/magic-classes/wiki/MagicClassesOverview

                  github.com/ded/klass
                  github.com/jiem/my-class
                  github.com/kilhage/class.js
                  github.com/Jakobo/Sslac
                  github.com/BonsaiDen/neko.js
                  github.com/finscn/GT-Class
                  github.com/deadlyicon/klass.js
                  github.com/neuromantic/CodeJS
                  github.com/cj/js-oo
                  github.com/darthapo/klass.js
                  github.com/nemisj/zet.js
                  github.com/k33g/species
                  github.com/benekastah/JS-Class
                  github.com/tobeytailor/def.js
                  github.com/rstrobl/squeakyJS
                  github.com/shinyplasticbag/MojoClass
                  github.com/firejune/class
                  github.com/gcoguiec/jquery-class
                  github.com/daffl/JS.Class
                  github.com/pavelz/class.js
                  github.com/zerodogg/jqsimple-class
                  github.com/bnoguchi/class-js
                  github.com/arian/Klass
                  github.com/kuwabarahiroshi/joo
                  github.com/iamleppert/SimpleClass
                  github.com/aenoa/Noode.js
                  github.com/stomlinson/SuperClass
                  github.com/jzimmek/klazz
                  github.com/kbjr/class.js
                  github.com/jhnns/node.class
                  github.com/borysf/declare/blob/master/declare.js
                  github.com/ShadowCloud/BF-Class
                  github.com/pic-o/jsClass
                  github.com/rosamez/jquery.klass
                  github.com/yuki-kimoto/javascript-Class_Simple
                  github.com/yaksnrainbows/jarb
                  github.com/thirashima/UnderClass
                  github.com/arahaya/package.js
                  github.com/arieh/Class.def
                  github.com/bogdan-dumitru/jsClass
                  github.com/pomke/pomke.js
                  github.com/sgolasch/jClassify
                  github.com/kbjr/Classy
                  github.com/cthackers/jClass
                  github.com/davidjbeveridge/Clasico
                  github.com/edave64/protojazz
                  github.com/mrac/solid.js
                  github.com/benekastah/Classy
                  github.com/damianmr/JSMiniClass
                  github.com/benekastah/classesWithCash
                  github.com/dialog/Resig-Class
                  github.com/mpodriezov/OJS
                  github.com/dtinth/twcs.js
                  github.com/percyhanna/js-class
                  github.com/jalopez/SimpleClassJS
                  github.com/jhamlet/proteus
                  github.com/petebrowne/classify
                  github.com/TdroL/Classy.js
                  github.com/azendal/neon
                  github.com/aulizko/Alan-Point-JavaScript-Library/tree/master/src/oop
                  • +6
                    Да, если кто-то знает еще реализации — пишите — добавим в коллекцию.
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • +5
                      Евгений — Вы все никак не уйметесь…
                      • НЛО прилетело и опубликовало эту надпись здесь
                        • –2
                          Судя по количеству ссылок она актуальная:)
                          • 0
                            Я так понял, если в ваших любимых книжках не написали, что идея ахуенная, то вы смело заявляете что идея говно. У Вас Евгений вообще есть собственное мнение?
                      • +5
                        Значит я всё сделал правильно Ж8-)
                        • +3
                          спасибо за ссылки
                        • +2
                          в мемориз!
                          • +2
                            Очень странно, уже довольно давно пишу на клиентском JS и ни разу мне не приходила в голову идея написать свою (или даже взять чужую) реализацию ООП. Не то чтобы необходимость в этом полностью отсутствует, но интерфейсы относительно легко пишутся и нативными средствами (хотя обычно я использую фреймворк).

                            Получается, что ООП в JS для меня как инструмент с узким кругом задач под него.
                            • +1
                              > Получается, что ООП в JS для меня как инструмент с узким кругом задач под него.
                              Да, обычно это имеет смысл лишь при написании крупных фреймворков, например при создании GUI фреймворка вроде ExtJS.
                              • +1
                                В том то и дело, я сам автор одного GUI-фреймворка, но за полтора года работы над ним, так и не смог понять зачем кому-то переносить ООП в JS «как есть». Единственная причина, это пожалуй, возможность использовать одну и ту же (или опять таки «похожую») архитектуру на клиенте и сервере.
                                • 0
                                  Ну, концепция виртуальных методов, например, на мой взгляд весьма практична при построении иерархии компонент в GUI.
                            • +2
                              все-таки чего-то не хватает.
                              пойду писать свою.
                                • +1
                                  А как же Joose. Там даже элементы ООП
                                  • 0
                                    не «ООП» — а AOP, извините :)
                                  • 0
                                    какой полезный списочек, в мемо :)
                                        • 0
                                          Странные вы. Любой разработчик с первого взгляда найдёт фатальный недостаток ( lurkmore.to/Фатальный_недостаток ) в каждой из этих реализаций.
                                        • +3
                                          Совсем забыли описать тонкости документирования(jsdoc) классов создаваемых через фабрики.
                                          • +7
                                            Ребята вот подборка книг хорошая:
                                            — JavaScript: The Definitive Guide, 5th Edition By David Flanagan
                                            — Pro JavaScript Techniques by John Resig
                                            — Pro JavaScript Design Patterns by Dustin Diaz and Ross Harmes
                                            — JavaScript: The Good Parts by Douglas Crockford
                                            Прочитайте вдумчиво, через пол года практики 100к+ гарантирую.
                                            Нужно читать правильных авторов.
                                            • 0
                                              У Флэнегана уже шестое издание вышло, пока только на английском.
                                              • 0
                                                есть что-то интересное?
                                                • 0
                                                  Новые главы про HTML 5, ECMAscript 5, структура старых глав переработана, новые примеры и объяснения. Ничего кардинального, но если читать первый раз, то лучше сразу шестое.
                                              • НЛО прилетело и опубликовало эту надпись здесь
                                              • 0
                                                Не хватает Object-Oriented JavaScript в тему статьи…
                                              • –1
                                                Почему никто не комментирует пример с Singleton? Этот код можно использовать везде где необходлимо применить паттерн Singleton.
                                                Ведь именно в подобных возможностях и есть основное отличие моего конструктора от множества подобных(если я не прав — киньте ссылку)
                                                • +1
                                                  Потому что Singleton делается так:
                                                  function Singleton() {
                                                  console.log('Instaniate')
                                                  }
                                                  Singleton.getInstance = function() {
                                                  Singleton.instance = Singleton.instance || new Singleton()
                                                  return Singleton.instance
                                                  }
                                                  Singleton.prototype.func = function(){}
                                                  var blabla = Singleton.getInstance().func()

                                                  Что короче вашего примера в два раза
                                                  • 0
                                                    «new Singleton()» создаёт экземпляр класса Singleton, а мой код создаёт через getInstance экземпляр нужного класса.
                                                    SuperDoggy.getInstance() — создаёт экземпляр класса SuperDoggy, а не Singleton.
                                                    • +5
                                                      Тру-синглтон в JS делается так:
                                                      var SingletonName = {
                                                      prop1: value,
                                                      method1: function() {}
                                                      }


                                                      Если нужно наследование, то пишется универсальная функция в три строки, которая позволяет наследовать один объект от другого, вообще безо всяких классов, конструкторов и т.п.
                                                      • 0
                                                        а в чём проблема унаследоваться как-то так?

                                                        var SingletonName = new Function();
                                                        
                                                        SingletonName.prop1 = value;
                                                        SingletonName.method1 = function() {};
                                                        
                                                        var SingletonChild = new SingletonName();
                                                        SingletonChild.subMethod = function () {}
                                                        
                                                        • +1
                                                          Это не работает. Свойства должны быть не у функции а у ее прототипа, чтобы наследоваться.
                                                          • 0
                                                            Да, глупость сморозил. Тогда так:
                                                            var SingletonName = new Function();
                                                            
                                                            SingletonName.prop1 = 123;
                                                            SingletonName.method1 = function() {};
                                                            
                                                            var SingletonChild = function () {
                                                              var Parent = new Function ();
                                                              Parent.prototype = SingletonName;
                                                              return new Parent();
                                                            }();
                                                            SingletonChild.subMethod = function () {}
                                                            
                                                            SingletonChild.method1()
                                                            


                                                            Хотя да — лучше врапнуть в функцию и использовать всегда, когда надо.
                                                            • 0
                                                              > Хотя да — лучше врапнуть в функцию и использовать всегда, когда надо.

                                                              Да, вот именно про это я и писал. Тем более что область применения этой функции из трех строк шире, чем просто создание синглтонов-наследников.
                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                    • +1
                                                      осуждаю
                                                      • +6
                                                        Такие топики и куски кода делают мне удивление. Смотришь на это, и кажется, что javascript в представлении нифиге не ООП язык только лишь из-за того, что там нет ключевых слов «class», «abstract», «extend».
                                                        Предлагаю вашему вниманию мини-топик(опубликую здесь же в каментах):

                                                        ООП в Javascript
                                                        function Clazz(){}
                                                        Clazz.prototype.foo = function(){}
                                                        var obj = new Clazz()


                                                        Та-дам!

                                                        Ну таки осуждаю
                                                        • –2
                                                          Смотришь на это, и кажется, что javascript в представлении нифиге не ООП язык только лишь из-за того, что там нет ключевых слов «class», «abstract», «extend».


                                                          Согласен! Однако стоит рассматривать мой код как удобную обёртку для тех возможностей языка, которые есть. Подобные конструкторы классов удобно форматируют ваш код. Всё разложено по полочкам, тут методы, тут статические, конструктор, видно что от чего наследуется итд.

                                                          Я не пытался максимально приблизиться к ООП. Мой конструктор классов всего лишь собирает класс. Из внутренних свойств добавлен только метод instanceOf
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                          • +2
                                                            Просто чаще всего программисты привыкли работать лишь с одной версией ООП — той, что реализована в Java/C#. Ну или в С++.
                                                            • +1
                                                              Дополню вашу реализацию переменными инстанса и статичными:

                                                              function Clazz(spam){
                                                              this.instanceProperty = spam;
                                                              }

                                                              Clazz.prototype.foo = function(){}
                                                              Clazz.staticProperty = 0;

                                                              var obj = new Clazz('egg')
                                                            • –1
                                                              А мне понравилось. Я не «скульный» javascript программист, на столько глубоко эту тему не знаю. А вашим «велосипедом» буду пользоваться. Если бы мог вам плюс поставить, поставил бы, но не могу :-)
                                                              • 0
                                                                Спасибо за ваш позитивный комментарий!
                                                                Судя по количеству плюсов у статьи и количеству закладок она написана не зря.
                                                              • 0
                                                                после прочтения пункта
                                                                2. Поддержка множественного наследования

                                                                сразу вопрос: каков порядок разрешения методов?
                                                                • 0
                                                                  Спасибо, первый вопрос по теме.
                                                                  Самого по себе разрешения конфликта между методами родительских классов нет.
                                                                  Если вдруг такая ситуация произойдёт, то можно её решить вручную:

                                                                  var Dog = createClass({
                                                                      extend: [Animal, OtherClass],
                                                                      say: function() {
                                                                          Animal.fn.say.call(this);
                                                                          OtherClass.fn.say.call(this);
                                                                          // ещё какой-то код
                                                                      }
                                                                  };
                                                                  

                                                                  Просто нужно понимать, что полноценной поддержки ООП в JavaScript нет, и тут не стоит строить безумные конструкции в попытке воспроизвести все возможности ООП. Нужно «понять и простить» JavaScript и пользоваться тем, что есть.

                                                                  • 0
                                                                    спасибо — возможный вариант понятен. просто, имхо, именно множественное наследование — «безумные конструкции в попытке воспроизвести все возможности ООП». вот когда стоит вопрос его использования — всегда приходит мысль — плохая архитектура. и его роль сводится к внедрению в текущую иерархию классов и соглашений. своего рода хак.
                                                                    • 0
                                                                      Не стоит зацикливаться на фразе «множественное наследование».
                                                                      По сути конструкция extend: [Animal, OtherClass] просто копирует свойства обьектов Animal, OtherClass в обьект Dog, а чем они являются (классами, интерфейсами, примесями) это вам решать.
                                                                      Не любите множественное наследование — не пользуйтесь, просто такая возможность есть и всё.
                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                  • 0
                                                                    Юзаю haxe для ООП и не парюсь. А для некоторых задач на чистом js хватает и прототипного наследования.
                                                                    • 0
                                                                      Интересно почему до сих пор придумывают как сделать js похожим на любой другой язык.
                                                                      js2c++, js2php, js2asm. Здорово что гибкость языка позволяет.

                                                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.