<div id="menu"> <button data-action="save">Сохранить</button> <button data-action="load">Загрузить</button> <button data-action="search">Поиск</button> </div> <script> function Menu(elem) { this.save = function() { alert( 'сохраняю' ); }; this.load = function() { alert( 'загружаю' ); }; this.search = function() { alert( 'ищу' ); }; var self = this; // зачем тут this, объясните пожалуйста дав полноценный ответ elem.onclick = function(e) { var target = e.target; var action = target.getAttribute('data-action'); if (action) { self[action](); // как работает это выражение? } }; } new Menu(menu); 

Closed due to the fact that the question is too general by the participants dirkgntly , user207618, user194374, aleksandr barakin , pavel Aug 6 '16 at 8:02 .

Please correct the question so that it describes the specific problem with sufficient detail to determine the appropriate answer. Do not ask a few questions at once. See “How to ask a good question?” For clarification. If the question can be reformulated according to the rules set out in the certificate , edit it .

  • one
    @ Konstantin Basharkevich - it is not clear to him - 1. what is this when calling a function as a constructor, 2. what is closure, where the self variable is available in the onclick handler, a this in this handler differs from this in the Menu . - Igor
  • @Igor yes, I didn’t immediately notice the comments, I apologize - Konstantin Basharkevich
  • and the rest of the code, except for these two lines is clear? - Grundy
  • Yes, I figured out the rest of the code. - Nikita

3 answers 3

In this case, the Menu function is used as a constructor. When you call it with the new : new Menu(menu) operator, inside it, this points to the new object being created.

Inside the click handler, this will already point to the element that was clicked and to call the methods of the Menu object being created inside the handler, the link to this object is stored in the self variable, which is used inside the handler.

More information about the loss of context can be found in the question: Loss of call context


To refer to the fields of the object in javascript there are two notations

  1. Dot-notation - access to the field through the point

     var o = { prop: 1; }; o.prop;// 1 

    This notation is widespread, but has restrictions on the names of fields to which it can be applied. So, to use this notation, the field name must be a valid identifier.

  2. Bracket-notation - reference to the field using brackets []

     var o = { prop: 1; }; o["prop"];// 1 

    This notation is widely used in cases where the name of the field to be addressed is not known in advance, as well as when the field name is not a valid identifier, but is for example a number or contains a space.

In this case, the property name is determined at the moment of the click, and the corresponding function is executed.


You can do without an intermediate variable if you use the arrow functions

 function Menu(elem) { this.save = function() { console.log('сохраняю'); }; this.load = function() { console.log('загружаю'); }; this.search = function() { console.log('ищу'); }; elem.onclick = (e) => { var target = e.target; var action = target.getAttribute('data-action'); if (action) { this[action](); } }; } new Menu(menu); 
 <div id="menu"> <button data-action="save">Сохранить</button> <button data-action="load">Загрузить</button> <button data-action="search">Поиск</button> </div> 

  • Cool. But still, I think it’s not worth encouraging authors with similar answers :) - dirkgntly
  • @dDevil, in general, if I could immediately point out as a duplicate of two questions - I would note :-) - Grundy
  • Surprised that no one noted - implicitly creating links to elements with id browser should not be used. - user207618
  • @Other, it seems to me in this case it does not matter - Grundy
  • Still - if someone asks for an explanation, you need to give him as much knowledge as possible, and these variables are a rather cunning hack worth knowing about. Although this is your answer - write what you want :) - user207618
 function Menu(elem) { this.save = function() { alert( 'сохраняю' ); }; this.load = function() { alert( 'загружаю' ); }; this.search = function() { alert( 'ищу' ); }; var self = this; // тут self будет равен объекту данной функции (класса) Menu elem.onclick = function(e) { var target = e.target; var action = target.getAttribute('data-action'); // данные атрибута в котором записано имя метода if ( action ) { self[action](); // вызываем метод нашего объекта Menu } }; } new Menu(menu); 

Described what they asked))

  • Why self will be exactly the object, as he points to it? - Nikita
  • The Menu function is called as a new Menu object. Well, in self we write this which is a link to the parent object. - webkostya
  • That is, in fact, if the Main function were not called as an object, would the self variable point to a window? - Nikita
  • In general, self points to an object not only because the function is called as an object, but also because it was overwritten here, if we wrote it like this _self, it would turn out that the reference to the object would be written to a simple variable, and self would save its initial value. I hope I did not confuse anyone)) - webkostya

Inside the second function will be its this, which has nothing to do with this from the "upper" code. To access this "top" this, we declared a variable. Not finding such a variable js inside a function, js will climb up, and rest on this "global" (in this context) self variable.

  • about the expression is wrong, there is not even an array in the code - Grundy
  • @Grundy, enlighten me then please :). I can assume that this is a dynamic call to one of the functions save, load, search. If so, please give more details about this. If not, tell me anyway :) - Vyacheslav Potseluyko
  • one
    @VyacheslavPotseluyko, a minute of pedantry)) There are no associative arrays in JavaScript, it has "objects that behave like associative arrays" or in other words "hash tables". And this is not an expression, but a call to the properties of objects or access to the elements of the hash table by key. Therefore, it is more correct to say not an array, but an object. And not an expression, but access to the property of the object. Something like this: quirksmode.org/js/associative.html - Alex Krass
  • @AlexKrass more often such minutes). Thank you) - Vyacheslav Potseluyko
  • I still do not fully understand. Why does the variable self point specifically to an object, and not to a window? I apologize if it is a very primitive question, I'm just not experienced yet. - Nikita