There is a code

function popup(){} popup.hello = function(){ $("#container").html('<div onclick="popup.bye()">Hello</div>') } popup.bye = function(){ alert("Bye"); } popup.hello() 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"></div> 

No matter how I tried to do it through classes, modules, or even in the OOP style, nothing happens.


So that there are no unnecessary questions with extra code and minuses, I decided to make the example more visual

 var module =(function (){ var instanceCount = 0; var CONSTANT_GlOBAL = Math.random(); function render(localRandom){ $("#container").append('\ <div onclick="module.create('+ instanceCount++ +')">\ Module №: '+ instanceCount +'\ <br>Instance random variable: '+localRandom+'\ <br>Module random constant: '+ CONSTANT_GlOBAL +'\ </div><br>'); } return { run: function(number){ var localRandom = Math.random(); render(localRandom,number); }, create: function(number){ this.run(number); } } }()); module.run(1); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"></div> 

  • five
    And why is OOP? - Qwertiy
  • Then, that the sausage from popup.method1, popup.method2, popup.method3, popup.property1 ... will soon appear ... etc. I want to encapsulate within a function with a constructor. - Alexey Alekseev
  • @ Alexey Alekseev I answered your question in the chat . - Codd Wrench
  • @Codd Wrench, So I wanted to see how you can thrust a class function call into a class definition. If I could create, I would create. What should I write in <button onclick = "???"> </ button> when this html is also inside one of the functions of the class? - Alexey Alekseev
  • @ Alexey element.find("a.close").click( see the line element.find("a.close").click( - Codd Wrench

3 answers 3

In general, the implementation of a pure OOP approach on js, up to the es6 standard , is one of the most non-trivial tasks and therefore it has many solutions:

Option 1 - find a suitable js library

There are many such libraries on the Internet, here are a couple of examples:

Option 2 - use js compiler

Too many options, for example:

  • Babel - compiles (translates) vanilla es6 code.
  • TypeScript is a separate js superset positioned as js c types.

Option 3 - write your own implementation

The answers already have the simplest implementation of a class using the module-pattern , but the OOP does not end there, but what about inheritance? In js, the inheritance mechanism via prototype is implemented like this:

 MyClass.prototype = Object.create(Base.prototype); 

But this will only copy the methods of the prototype, and we still have the properties of the object itself - in OOP these are static methods and properties, so I use the following pattern:

 function extend(current, base) { // копируем статические проперти for (var key in base) { if (base.hasOwnProperty(key)) { current[key] = base[key]; } } // копируем прототип current.prototype = Object.create(base.prototype); }; 

Now you can use it:

 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 = {})); 

In your code, you create a scope (namespace) of Dialogs within which all the magic happens, and you can also declare global variables in it:

 var Dialogs; (function (Dialogs) { var a = 100; // переменная видна внутри Dialogs Dialogs.b = 100; // можно обратиться как к Dialogs.b снаружи ... 

You can of course without it, then the class pattern will look like this:

 var Popup2 = (function (superClass) { extend(Popup2, superClass); function Popup2() { superClass.apply(this, arguments); } return Popup2; }(Popup)); 

see how it works here: jsfiddle

  • Comments are not intended for extended discussion; conversation moved to chat . - Nicolas Chabanovsky
  • As if in es6, something other than makeup was added in terms of supporting the PLO. - Vladimir Gamalyan
  • @VladimirGamalian, I did not claim that es6 solves all problems, just with its appearance, writing OOP code has become more trivial. - Codd Wrench
  • What exactly makes esp writing more trivial in es6? - Vladimir Gamalyan
  • @VladimirGamalian syntactic sugar - keywords class , extends , etc. more here . That is, the need to use the tools from the first points disappears. - Codd Wrench

Can you use React?

 class Popup extends React.Component { constructor(props) { super(props); this.bye = this.bye.bind(this); } render() { return <div onClick={this.bye}>{this.props.msg}</div>; } bye() { alert("Bye"); } } class App extends React.Component { render() { return <Popup msg="Hello"/>; } } ReactDOM.render(<App />, document.getElementById('container')); 
 <script src="//cdnjs.cloudflare.com/ajax/libs/react/15.4.0/react.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/react/15.4.0/react-dom.js"></script> <div id="container"></div> 

  • No, vanilla js with jQuery. But I like the direction. - Alexey Alekseev
  • one
    And what are the minuses showered? The class of the DOM element React looks like a very adequate abstraction for the popup object described in the question. Of course, for the sake of such a small example, the whole React is not worth it, but the author clearly stressed that the example is a toy and the object has all the chances to grow. - D-side Nov.
  • one
    That's right. But the reagent pull - rewrite the entire application. - Alexey Alekseev
 var Popup = function () { this.hello = function() { $("#container").html('<div onclick="popup.bye()">Hello</div>') }, this.bye = function(){ alert("Bye"); } } var popup = new Popup; popup.bye() 
  • 3
    onclick="popup.bye()" - binding to a global variable is just a great OOP. - Qwertiy
  • @Qwertiy He will have to solve this problem himself) since he will not work. - pwnz22
  • in fact, it was from you that the decision was expected ... - Pavel Mayorov
  • I tried. But it is unacceptable for me to stitch an instance in the constructor. - Alexey Alekseev