Страницы

Поиск по вопросам

воскресенье, 2 февраля 2020 г.

Помогите процедурщику переписать маленький скриптик на javascript в ООП стиле

#javascript #ооп


Есть код



function popup(){}
popup.hello = function(){
  $("#container").html('
Hello
') } popup.bye = function(){ alert("Bye"); } popup.hello()
Как ни пробовал его сделать через классы, модули или вообще в ООП стиле, ничего не получается. Так, чтобы не было лишних вопросов с лишним кодом и минусов, решил сделать пример более наглядным var module =(function (){ var instanceCount = 0; var CONSTANT_GlOBAL = Math.random(); function render(localRandom){ $("#container").append('\
\ Module №: '+ instanceCount +'\
Instance random variable: '+localRandom+'\
Module random constant: '+ CONSTANT_GlOBAL +'\

'); } return { run: function(number){ var localRandom = Math.random(); render(localRandom,number); }, create: function(number){ this.run(number); } } }()); module.run(1);


Ответы

Ответ 1



Вообще реализация чистого ООП подхода на js, до стандарта es6, это одна из самых нетривиальных задач и поэтому у нее есть множество вариантов решения: Вариант 1 - найти подходящую js библиотеку Таких библиотек в интернете множество, вот пара примеров: jsface classify Вариант 2 - использовать js compiler Тоже множество вариантов, например: Babel - компилирует(транслирует) ванильный es6 код. TypeScript - отдельное надмножество js, позиционируемый как js c типами. Вариант 3 - написать свою реализацию В ответах уже есть простейшая реализация класса с использованием module-pattern, но ООП на этом не заканчивается, а какже наследование? В js уже реализован механизм наследования через prototype вот так: MyClass.prototype = Object.create(Base.prototype); Но это скопирует только методы прототипа, а у нас есть еще свойства самого объекта - в ООП это статические методы и свойства, поэтому я использую следующий паттерн: function extend(current, base) { // копируем статические проперти for (var key in base) { if (base.hasOwnProperty(key)) { current[key] = base[key]; } } // копируем прототип current.prototype = Object.create(base.prototype); }; Теперь можно это использовать: var Dialogs; (function (Dialogs) { // класс Popup Dialogs.Popup = (function () { // статическая функция Popup.show = function () { alert("show"); }; // Конструктор класса function Popup(message) { this._message = message; } Popup.prototype.hello = function () { var self = this; var message = $(this._message).click(function () { self.sayBye(); }); $("#container").append(message); }; Popup.prototype.sayBye = function () { alert("Bye"); }; Popup.prototype.say = function () { alert(this._message); }; return Popup; }()); // класс Popup2 extend Popup Dialogs.Popup2 = (function (superClass) { // наследуем прототип extend(Popup2, superClass); function Popup2() { // вызываем конструктор базового класса superClass.apply(this, arguments); } // перегружаем базовую функцию sayBye Popup2.prototype.sayBye = function () { alert("Bye2"); }; return Popup2; }(Dialogs.Popup)); // передаем базовый класс })(Dialogs || (Dialogs = {})); В коде ваше создается область видимости(namespace) Dialogs внутри которой происходит вся магия, так же в ней можно объявлять глобальные переменные: var Dialogs; (function (Dialogs) { var a = 100; // переменная видна внутри Dialogs Dialogs.b = 100; // можно обратиться как к Dialogs.b снаружи ... Можно конечно и без нее тогда паттерн класса будет выглядеть так: var Popup2 = (function (superClass) { extend(Popup2, superClass); function Popup2() { superClass.apply(this, arguments); } return Popup2; }(Popup)); посмотреть как это работает можно тут: jsfiddle

Ответ 2



А React использовать можно? class Popup extends React.Component { constructor(props) { super(props); this.bye = this.bye.bind(this); } render() { return
{this.props.msg}
; } bye() { alert("Bye"); } } class App extends React.Component { render() { return ; } } ReactDOM.render(, document.getElementById('container'));


Ответ 3



var Popup = function () { this.hello = function() { $("#container").html('
Hello
') }, this.bye = function(){ alert("Bye"); } } var popup = new Popup; popup.bye()

Комментариев нет:

Отправить комментарий