Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.01.2018, 20:55
Новичок на форуме
Отправить личное сообщение для Alex7851 Посмотреть профиль Найти все сообщения от Alex7851
 
Регистрация: 07.01.2018
Сообщений: 2

Как изменить контекст при помощи 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"?
Ответить с цитированием
  #2 (permalink)  
Старый 07.01.2018, 21:10
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,491

Во первых: не
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, как будто её и нет.
__________________
29375, 35

Последний раз редактировалось Aetae, 07.01.2018 в 21:14.
Ответить с цитированием
  #3 (permalink)  
Старый 07.01.2018, 21:19
Новичок на форуме
Отправить личное сообщение для Alex7851 Посмотреть профиль Найти все сообщения от Alex7851
 
Регистрация: 07.01.2018
Сообщений: 2

Aetae, огромное Вам спасибо за обстоятельный ответ!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как изменить значение Value Doc_Emmett Brown Opera, Safari и др. 5 05.10.2022 19:53
Как реализовать перезагрузку скриптов/функций при подгрузке контента с помощью AJAX? yii2 jQuery 2 27.09.2017 19:48
Как изменить цвет текста в таблице при наведении на нее? Amateur jQuery 3 01.09.2012 06:19
Как сделать что бы при регистрации человека на моем сайте у него не появлялось... drunkwolfs Общие вопросы Javascript 2 07.08.2012 10:58
Подскажите как при помощи JS hta в трею свернуть kimboo Общие вопросы Javascript 4 11.07.2008 16:00