Как изменить контекст при помощи call?
Вопрос носит скорее теоретический характер.
Имеем простейшую задачу вызвать метод класса по щелчку на кнопку. Собственно сам работающий код: <body> <input type="button" value="OK"> </body> function NewClass() { this.show= function() { alert("Some message"); } } button=document.querySelector('input[type=button]'); newClass= new NewClass; button.onclick= function() { newClass.show() } Меня интересует установка слушателя (11-13 строки кода).Правильно ли я понимаю, что button.onclick=newClass.show() не вариант т.к. контекст в данном случае будет = window и обертка в функцию в данном случае нужна для того, чтобы функция взяла "на себя" контекст window, а в самом вызове метода класса this соответствовал экземпляру созданного класса? Также у меня возникает второй вопрос: можно ли обойти эту обертку функцией вызываемого метода при подвешивании слушателя, при помощи CALL? Т.е. передать контекст принудительно типа так: button.onclick=newClass.show().call(newClass) Но так к сожалению не получается: alert выскакивает при загрузке страницы, а сам button.onclick=null, если смотреть из браузера. Вопрос: почему данном случае слушатель отваливается? Ведь контекст я передаю и this=object (проверял alert-ом в this.show). Есть ли альтернативное решение с "call"? |
Во первых: не
button.onclick=newClass.show();а button.onclick=newClass.show;потому что скобочки в конце метода это уже вызов, вот прям сейчас, на месте. Во вторых: в современном js есть медот функции bind, это именно то о чём вы спросили: button.onclick=newClass.show.bind(newClass);Но по сути он аналогичен тому самому первому созданию новой функции изнутри которой вызывается метод в правильном контексте. И в-третьих: многие пользуются всяческими вариациями привязки this, однако это всё в современном js на самом деле костыли. Единственный верный вариант(на мой взгляд), это использовать addEventListener и передавать ему не функцию но сам объект, имеющий метод handleEvent: function NewClass() { this.show= function() { alert("Some message"); } } NewClass.prototype={ handleEvent: function(event){ switch(event.type){ case 'click': this.show(event); break; //... } } } button=document.querySelector('input[type=button]'); newClass= new NewClass; button.addEventListener('click', newClass);Таким образом прекрасно отделяется обработка событий от всего остального, и попутно решается проблема с this, как будто её и нет. |
Aetae, огромное Вам спасибо за обстоятельный ответ!
|
Часовой пояс GMT +3, время: 07:05. |