С Новым годом! Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
 Аватар для prudkiy
181 / 149 / 55
Регистрация: 21.07.2013
Сообщений: 958

Передача контекста, bind

28.01.2019, 11:42. Показов 2850. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго )
Помогите решить проблему.
Есть у меня объект, есть метод где назначается обработчик для события.
Мне нужно при событии, отловить в функции контекст как объекта так и непосредственно элемента на котором произошло события (надеюсь ясно объяснил )) ) .
Я думаю лучше всего подходит метод bind, чтоб привязать контекст но сколько не читая док так и не могу реализовать.
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class object {
        constructor () {
            this.index = 1;
            this.countSlide = 0;
            this.button = document.getElementById('but1');
        }
}
 
object.prototype.test = function() { 
        this.button.addEventListener('click', object.myBut.bind(this));
}
 
object.myBut= function (box) { 
        console.log(box.index);
        console.log(this.getAttribute('id')); // консоль скажет что getAttribute не является функцией, в случаи когда есть привязка bind
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.01.2019, 11:42
Ответы с готовыми решениями:

Привязка контекста к {}
Можно привязать контекст к объекту? var obj1 = { prop: 1, method: { set: function () { return...

Потеря контекста
Доброго времени суток. Помогите понять следующий пример: взят от сюда https://learn.javascript.ru/bind var user = { ...

Задание контекста в сallback-функциях
Всем привет! В последние время JS становится всё асинхронее и повсюду используются callback'и. Классная штука, однако проблема в том,...

14
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
28.01.2019, 13:55
что вывел console.log(box.index);?
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
28.01.2019, 14:48
Вариант по-старинке без bind:
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <input type="button" id="but1" value="OK" />
    <script>
        class Btn {
            constructor() {
                this.index = 1;
                this.countSlide = 0;
                this.button = document.getElementById('but1');
            }
            test(clickHandler) {
                this.button.addEventListener('click', () => { clickHandler(this); });
            }
        }
        let btn = new Btn();
        btn.test(myHandler);
 
        // Произвольный внешний обработчик события click
        function myHandler(box) {
            console.log(box.index);
            console.log(box.button.getAttribute('id')); // консоль скажет что getAttribute не является функцией, в случаи когда есть привязка bind
        }
    </script>
</body>
</html>
Сейчас буду вспоминать, на фейхоа вообще этот bind нужен...
1
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
28.01.2019, 14:51
amr-now, у bind первым идет текущий объект, тот который будет использоваться..
Как бы идет заимствование метода
JavaScript
1
this.button.addEventListener('click', object.myBut);
без this, object.myBut будет указывать на this.button, но object.myBut.bind(this) мы передаем объект this, и теперь this указывает не на this.button, а на this (речь о object.myBut)
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
28.01.2019, 14:56
prudkiy, EveKS,
а вот здесь поподробнее, пожалуйста.
myBut где вообще живёт? Мы её подрисовываем от балды когда-нибудь потом,
или myBut автоматически появляется при создании экземпляра обёртки над кнопкой?

Добавлено через 2 минуты
Сейчас функция выглядит как намертво вшитая статическая функция класса:
JavaScript
1
2
3
4
object.myBut= function (box) { 
        console.log(box.index);
        console.log(this.getAttribute('id')); // консоль скажет что getAttribute не является функцией, в случаи когда есть привязка bind
}
Это намертво вшитая статическая функция класса, никогда не изменяемая?
0
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
28.01.2019, 15:02
amr-now, мы всего лишь указываем текущий объект, object.myBut.bind(this), где он будет жить, об этом не могу сказать.
Функция статическая, действительно. Почему я спросил про console.log(box.index);, без проверки кода не могу понять, что это за box... event или undefinde
Вот так object.myBut.bind(this, this) box это class object
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
28.01.2019, 15:22
Цитата Сообщение от EveKS Посмотреть сообщение
где он будет жить, об этом не могу сказать.
Это самое главное.
Если статическая функция класса, то никаких извращений не надо. Класс сам знает, что у него есть свойство-значение button.

Добавлено через 9 минут
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <input type="button" id="but1" value="OK" />
    <script>
        class Btn {
            constructor() {
                this.index = 1;
                this.countSlide = 0;
                this.button = document.getElementById('but1');
            }
            test() {
                this.button.addEventListener('click', () => { Btn.myBut(this); });
            }
            static myBut(box) {
                console.log(box.index);
                console.log(box.button.getAttribute('id'));
            }
        }
        let btn = new Btn();
        btn.test();
    </script>
</body>
</html>
Добавлено через 7 минут
всем спасибо. Есть, куда запихать bind ))
addEventListener() требует для обработчика первым параметром event,
значит в статическом методе класса нельзя использовать параметры ))
В JavaScript в статическом методе разрешено использовать this.
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <input type="button" id="but1" value="OK" />
    <script>
        class Btn {
            constructor() {
                this.index = 1;
                this.countSlide = 0;
                this.button = document.getElementById('but1');
            }
            test(clickHandler) {
                this.button.addEventListener('click', Btn.myBut.bind(this));
            }
            static myBut(box) {
                console.log(this.index);
                console.log(this.button.getAttribute('id'));
            }
        }
        let btn = new Btn();
        btn.test();
    </script>
</body>
</html>
0
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
28.01.2019, 15:56
Цитата Сообщение от amr-now Посмотреть сообщение
test(clickHandler) {
this.button.addEventListener('click', Btn.myBut.bind(this));
}
static myBut(box)
{
console.log(this.index);
console.log(this.button.getAttribute('id '));
}
=)) Я об этом и говорил, что при Btn.myBut.bind(this), this внутри Btn.myBut будет указывать на объект class Btn, без bind на this.button

Добавлено через 7 минут
Освежил память в теории об частичное применение функции
function.bind всегда возвращает другую функцию, даже если мы предоставили все аргументы базовой функции.
Добавлено через 51 секунду
Это о том, а где же она живет
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
28.01.2019, 16:18
Цитата Сообщение от EveKS Посмотреть сообщение
function.bind всегда возвращает другую функцию
Что подтверждает, что в данном примере обе обертки на обработчик в ответе №7
являются примерно равноценными костылями.
Что в принципе и объясняет нераспространённость bind() в других языках.
0
 Аватар для prudkiy
181 / 149 / 55
Регистрация: 21.07.2013
Сообщений: 958
29.01.2019, 03:16  [ТС]
Хюх, еле до ноута добрался ) Заранее всем огромное спасибо за ответы, вообще приятно что так откликнулись ) Вообщем я решил не заморачивать что и как есть, упростил пример.
Я пытаюсь сам написать карусель используя ооп javascript
С ооп вообще слаб, только его изучаю, ноооо я упертый )))

Написал класс и пару методов
Прошу не судить строго, буду еще допиливать. Критику воспринимаю норм, какие есть замечания по уже написаному коду, буду рад услышать (ну или прочитать )
Вот что набросал, пока не уперся в вопрос с которым сюда пришел
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    class CaruselPs {
 
        constructor (divClassWrapMain, divClassWrap, marginRight = '0', classWrapBut = false) {
 
            this.index = 1;
            this.countSlide = 0;
            this.showButNav = classWrapBut;
            this.marginSlide = marginRight;
            this.wrapCaruselMain = document.querySelector(divClassWrapMain); // доступ к основной обложке карусели
            this.wrapCarusel = document.querySelector(divClassWrap); // доступ к внутренней обложке карусели
            this.elCarusel = this.wrapCarusel.querySelectorAll('.item'); // выбор элементов в обложке
            this.widthEl = this.elCarusel[1].offsetWidth; // ширина одного элемента
            if (classWrapBut) this.wrapBut = document.querySelector(classWrapBut); // обложка для кнопок, если нужно
 
            this.elCarusel.forEach(function(item, i, arr){ // проход по выбранным элементам в обложке
                item.style.marginRight = marginRight+'px'; // установка отступа у элементов с права в обложке (по умолчанию 0)
            });
 
            this.slideLeft();
            this.readyBut();
            
        }
 
        readyBut () { // реализация кнопок
            this.countSlide = (this.elCarusel.length) - 2;
            let htmlBut = '';
            for (let i = 1; i <= this.countSlide; i++) {
                if (i === 1 ) htmlBut += `<span class="blockCarusel1__but--act" id="blockCarusel1__slide__${i}"></span>`;
                else  htmlBut += `<span id="blockCarusel1__slide__${i}"></span>`;
            }
            this.wrapBut.innerHTML = htmlBut;
        }
 
        slideLeft () { // метод сдвига элементов влево
            this.wrapCarusel.style.transform = `translateX(-${(this.index * this.widthEl)+15}px)`;
        }
    
    }
    
let carusel1 = new CaruselPs ('.blockCarusel1__img--wrap', '.blockCarusel1__carousel', '15', '.blockCarusel1__but'); // параметры = (класс главной обложки, класс непосредственной обложки, отступ элемента, класс обложки для кнопок(если не нужно то false), класс активная кнопка)
Нужен метод (функция) в которой будет доступ как к свойствам объекта так и к свойствам кнопки по которой был клик

Добавлено через 34 минуты
Придумал так вот но думаю что точно есть варианты красивей.
дописал метод который назначит обработчик для сгенерированных кнопок и вызвал его в конструкторе - handlerButClick . И метод который будет получать параметры из вне - buttonCarusel
JavaScript
1
2
3
4
5
6
7
8
9
handlerButClick () { // назначим обработчик для кнопок 
            this.wrapBut.querySelectorAll('span').forEach(function(item, i, arr){ 
                item.addEventListener('click', handlerBut)
            });
}
buttonCarusel (attrId) {
            console.log(this.widthEl);
            console.log(attrId);
}
после объявления экземпляра класса прописал эту функцию (handlerBut).
Функция вызывает метод объекта с нужными мне аргументами кнопки
JavaScript
1
2
3
function handlerBut () {
    carusel1.buttonCarusel (this.getAttribute('id'));
}
0
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
29.01.2019, 06:18
Цитата Сообщение от prudkiy Посмотреть сообщение
Заранее всем огромное спасибо за ответы, вообще приятно что так откликнулись
А откликнулись-то зря... Ибо ни читали ни чего
В двух словах
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
class MyButton() {
  constructor(id) {
    this.button = document.getElementById(id);
    this.button.onclick = btnClick.bind(this);
  }
 
   function btnClick() {
      // наша button
      console.log(this.button);
      // наш класс
       console.log(this);
   }
}
0
29.01.2019, 06:29

Не по теме:

EveKS,

Цитата Сообщение от EveKS Посмотреть сообщение
А откликнулись-то зря
ну почему же - зря? ТС не единственный, кто будет читать тему. Я думаю гостей нормально набежит за месяц в поисках ответа на подобный вопрос.

0
29.01.2019, 06:46

Не по теме:

Qwerty_Wasd, с этой точки зрения, с вами соглашусь

0
74 / 29 / 4
Регистрация: 16.10.2017
Сообщений: 95
29.01.2019, 18:01
Цитата Сообщение от EveKS Посмотреть сообщение
А откликнулись-то зря... Ибо ни читали ни чего
В двух словах
Ваш код тоже нерабочий ...
0
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
29.01.2019, 18:11
timen, мой код не рабочий из-за синтаксических ошибок, и набирался он как пример для понимания...
для тех кому нужен рабочий вариант

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyButton {
  constructor(id) {
    this.button = document.getElementById(id);
    this.button.onclick = this.btnClick.bind(this);
  }
 
   btnClick()  {
      // наша button
      console.log(this.button);
      // наш класс
       console.log(this);
   }
}
 
(() => {
    let btn = new MyButton('clickMe');
})();
ссылка
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.01.2019, 18:11
Помогаю со студенческими работами здесь

Инструменты для просмотра контекста замыкания
Столкнулся с такой проблемой: есть много функций, замкнутых относительно некоторых объектов, например,function add(x) { return...

Отличия call (apply) от bind
Доброго времени суток! Есть такой вопрос! Не могли бы мне обьяснить, когда именно используется call (apply) и когда bind? И, если есть...

Функция bind textchange выполняется дважды
Объясните пожалуйста, почему следующий код: $(document).ready(function() { $('#find_field_label').bind('textchange', function() { ...

Передача std::bind в функцию
Ребята, помогите разобраться с 28 строкой. Глубоко не копал, но должно ведь компилиться :) #include &lt;iostream&gt; #include...

Передача контекста во внешнюю форму ТиС9.2
Сделал полную копию базы, изменил форму двух документов (добавил вызов обработки из формы), после чего при обращении из этих документов к...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru