📜 ⬆️ ⬇️

Kung Fu: javascript style

This article began as a comment on another article on habrahabr . After writing the first sheet, I realized that the comment was too extensive :). I decided to write, because I want to focus on points that, in my opinion, were missed. The limitation of this article is my goal to state everything as accessible as possible, do not look here for mathematical accuracy in the definition of terms, and yet I attach links where mathematicians will find high-class definitions understandable only to them :)

Probably every article on JS is made to begin with words about its undervalued :) It's true :) When I said a couple of years ago that JS was my favorite language, they looked at me as an overgrown schoolchild who had just written his first page on HTML and those who knew me, like a grandmaster, who said that he only knows how the pieces go :). Such people did not become much less, alas: (

So, the first moment - nothing is said about how Javascript differs fundamentally from Java or C ++. The difference in the approach ( paradigm ) of programming taken as a basis when creating a language. I do not appreciate “what is better?”, Neither in the coma case, which is more convenient :) or like :)
')

The difference between the traditional class-object and the prototype paradigm


Most people who look down on JS talk about him as if not about OOP language :). To begin with, these are different things and cannot be compared at all. Of course, you can program in JS using the skills learned from programming in C ++ or Java, but this is not so effective. JS works differently, there are no classes in it, there are objects in it (do not faint, read the article). This does not mean that it is impossible to do abstraction , encapsulation , inheritance or polymorphism in JS. The main differences in the implementation of encapsulation , inheritance , and the work of the designer. In JS, as in almost all prototype languages, the term encapsulation should be used; there is a closure .

Short circuit


I note that on Habré was already an article about closures . I will try to explain "on the fingers" and add an example.

The closures in JS call the scope within which the variable makes sense :). This may be a definition of an object or function. A variable can be either primitive, or an object or function. Phew ... now, my favorite, example:
function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  1. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  2. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  3. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  4. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  5. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  6. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  7. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  8. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  9. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  10. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  11. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  12. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  13. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  14. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  15. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  16. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  17. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  18. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
  19. function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
function bicubic(count) { var values = []; for ( var i = 0; i < count; i++) { values[i] = ( function (n) { return function () { return Math.pow(n, 3); } } )(i); } return values; } var vals = bicubic(10); alert( vals[3]() ); * This source code was highlighted with Source Code Highlighter .
If I were shown these lines and asked to say “what the hell is this”, I would spend more than one minute to figure it out :) This is what gives the supporter JS so much strength in the statement that class-based languages ​​lead to excessive when writing code Programmers focus on hierarchy and class relationships with each other, which in my opinion is true.

Let's take it in order :)
  1. A bicubic function is created that produces an array;
  2. The trick is that the array members are functions without a parameter: Math.pow (n, 3). In this case, n, thanks to the miracle of the circuit, becomes the value of i at the time of the cycle, and not after it!
  3. The magic in brackets (...) (i) is a function call with the parameter i, and in brackets the definition of this function.

since after the cycle i = count, then without these brackets, we get a completely different answer - a constant 10'000, and with them 27.

By the way, this technique is called closure break.

That is why jQuery recommends writing plugins for this framework inside the construct (... your plugin ...) () ;, it allows you to:
  1. Write safe code
  2. Do not overload the browser with global variables.

Instance, constructor, object and prototype


So I recently wrote that in JS there are no classes, but there are objects. I meant the following:

In class-oriented languages, a new instance is created through a call to the class constructor (possibly with a set of parameters). The resulting instance has a structure and behavior that is strictly defined by its class. Here are the lines from Wikipedia:
In prototype-oriented systems (for example, JS), two methods are provided for creating a new object: cloning an existing object, or creating an object from scratch . To create an object from scratch, the programmer is provided with syntactic means of adding properties and methods to the object. Further, a complete copy of the clone can be obtained from the resulting object. In the process of cloning a copy inherits all the characteristics of its prototype, but from that moment it becomes independent and can be changed. In some implementations, copies store references to prototype objects, delegating to them some of their functionality; however, the prototype change may affect all copies. In other implementations, new objects are completely independent of their prototypes.
Demonstration:
  1. function win () {
  2. this .open = function ()
  3. {
  4. return "open 1" ;
  5. }
  6. }
  7. win.open = function () {
  8. return "open 2" ;
  9. }
  10. alert (win.open ()); // 1. open 2
  11. win.prototype = {
  12. save: function ()
  13. {
  14. return "open 3" ;
  15. }
  16. }
  17. alert (win.save ()); // 2. error - no save
  18. win.prototype.open = function ()
  19. {
  20. return "open 4" ;
  21. }
  22. alert (win.open ()); // 3. open 2
  23. var vista = new win ();
  24. alert (vista.open ()); // 4. open 1
  25. alert (vista.save ()); // 5. open 3
  26. vista.open = (
  27. function ()
  28. {
  29. return "open 5" ;
  30. }
  31. ) ();
  32. alert (vista.open); // 6. open 5
  33. alert (win.open ()); // 7. open 2
* This source code was highlighted with Source Code Highlighter .

"Open 4" we will not get, because The open method is defined in the object itself, which does not apply to save.

An attentive reader will ask me - where is the designer in this devilish mixture? Yes, he was not here. The constructor is the object itself, started when the clone is created, using the new operator or initializing the object itself. Demonstration:
  1. function win ()
  2. {
  3. var str = "open 1" ;
  4. this .open = function ()
  5. {
  6. return str;
  7. }
  8. }
  9. alert (( new win ()). open ()); // open 1
* This source code was highlighted with Source Code Highlighter .
Creating an object "from scratch" in JS, "this thing"! I will give an example that helps save the muscular efforts of the fingers:
  1. function plugin (options)
  2. {
  3. options = options || {};
  4. options.list = options.list || [];
  5. // then you can safely work
  6. // options, check its properties, for example,
  7. // a with list as with an array
  8. }
* This source code was highlighted with Source Code Highlighter .


Prototype, "inheritance" in javascript



It is very difficult to find a black cat in a dark room, especially if it is not there :)
© folk wisdom

In JS, there is no inheritance and especially plural. Each object has a prototype, an object which can be shared among several objects or their copies, and then changed :)


Total


Guys praying on the OOP paradigm, wake up, there are many other programming paradigms. There is no best, there are the most suitable for certain tasks. JS is one of the languages ​​in the long-occupied niche, including because under it is a very powerful foundation of the prototypical programming paradigm .

The rest, I hope to learn something useful :)

Sincerely, Arthur Dudnik
The most valuable human trait - the desire for self-improvement ©

Source: https://habr.com/ru/post/49772/


All Articles