Задать вопрос
DieZz
@DieZz

Почему не работает объект?

Доброго времени суток. Пытаюсь понять ООП в js. Есть такой объект:
function Counter(start){
    this.value = start;

    this.Up = function()
    {
        this.value++;
        this.ShowText();
        console.log(this.value);
    };

    this.Down = function()
    {
        this.value--;
        this.ShowText;
        console.log(this.value);
    };

    this.ShowText = function()
    {
        $('.box').text(this.value);
    };

    this.Render = function()
    {
        $('#counter-minus').click(this.Down);
        $('#counter-plus').click(this.Up);
    }
}

counter = new Counter(2);
counter.Render();

Назначение объекта: при нажатии на + или - уменьшать или увеличивать значение переменной. Пример разметки:
<div class="counter">
                 <span class="control-counter" id="counter-minus">&minus;</span>
                 <div class="box">2</div>
                 <span class="control-counter" id="counter-plus">+</span>
</div>

Данный код не работает и почему понять не могу. Методы Up и Down срабатывают, но значения переменной value = NuN.
  • Вопрос задан
  • 281 просмотр
Подписаться 1 Оценить Комментировать
Решения вопроса 4
Petroveg
@Petroveg
Миром правят маленькие с#@&ки
Потому, что вы в обработчике события получаете в this ссылку на тот элемент, в котором обработчик был зарегистрирован.
Вам следует что называется «забиндить» обработчик на ваш объект.
Пример (вынес все методы в прототип, что есть правильно)

Вариант 1
this.Up = function () {
	...
}.bind(this);

this.Down = function () {
	...
}.bind(this);

Вариант 2
this.Render = function () {
	$(document)
		.on('click', '#counter-minus', this.Down.bind(this))
		.on('click', '#counter-plus', this.Up.bind(this));
}

Вариант с каррированием
function Counter(start){
	var xxx = this;
	//А тут везде внутри функций вместо this фтыкаем xxx
}

Последний вариант плох тем, что лишает возможности использовать прототип. Поэтому смотрите в сторону первых двух.
Ответ написан
Комментировать
Проблема в том, как Вы устанавливаете обработчик события на минус и плюс.
$('#counter-minus').click(this.Down);
Таким образом Вы только указываете, какой должен вызываться обработчик события, но контекст функции ей не передается. По сути функция Down вызвана в контексте элемента counter-minus, поэтому this там элемент.

Решить проблему можно с помощью метода bind, задав нужный контекст.
$('#counter-minus').on('click', this.Down.bind(this));
Ответ написан
Комментировать
@serega_kaktus
Программист-самоучка, фрилансер
function Counter(start){
  var that = this;

    this.value = start;

    this.Up = function()
    {
        that.value++;
        that.ShowText();
        console.log(that.value);
    };

    this.Down = function()
    {
        that.value--;
        that.ShowText;
        console.log(that.value);
    };

    this.ShowText = function()
    {
        $('.box').text(this.value);
    };

    this.Render = function()
    {
        $('#counter-minus').click(this.Down);
        $('#counter-plus').click(this.Up);
    }
}

counter = new Counter(2);
counter.Render();

jQuery выполняет обработчик события в контексте того элемента, на который этот обработчик был навешан. Короче говоря, в методах Up и Down this - это не ваш объект, а объект DOM.

А вообще не устанавливайте методы "класса" как обработчик события, лучше создайте анонимную функция и в ней вызовите нужный метод. Так избежите проблем.
И используйте прототипирование, а то ваше ООП бесполезно, наследование работать не будет
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
BuriK666
@BuriK666
Компьютерный псих
в this.Up
сделайте console.log(this) и все станет ясно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы