0

Обучаюсь по книжке Js for Kids (12 глава). В упражнении нужно сделать машинку, которая "едет" по экрану. Никак не могу понять, почему закомментированная строка не работает? Сама книга этот момент не освящает, а гугл только еще больше запутал.

let Car = function (x, y) {
    this.x = x;
    this.y = y;
};

Car.prototype.draw = function () { let carHtml = '<img src="images/car.png">';

this.carElement = $(carHtml);

this.carElement.css({
    position: &quot;absolute&quot;,
    left: this.x,
    top: this.y
});

$(&quot;body&quot;).append(this.carElement);

};

Car.prototype.moveRight = function () { this.x += 5; this.carElement.css({ left: this.x, top: this.y }); };

let nissan = new Car(100, 200);

nissan.draw();

// nissanMoveTimer = setInterval(nissan.moveRight, 1000); // Cannot read property 'css' of undefined nissanMoveTimer = setInterval(function () { nissan.moveRight(); }, 1000); // Рабочий код

setTimeout(function () { clearInterval(nissanMoveTimer);}, 5000);

  • Моё понимание кода: setInterval(nissan.moveRight, 1000); // Вызывать метод moveRight объекта nissan каждую секунду.

    setInterval(function () { nissan.moveRight(); }, 1000); // Создать функцию, разово выполняющую код внутри метода moveRight и вызывать её каждую секунду.

    Смысл одинаковый, второй вариант даже кажется избыточным, однако работает только он. С последней строкой, где clearInTerval, ситуация такая же - работает, только если расписать function () {func}; в первом аргументе.

    – Дмитрий Oct 16 '20 at 18:33
  • setInterval(nissan.moveRight.bind(nissan), 1000) – vp_arth Oct 16 '20 at 19:25

2 Answers2

0

Вам правильно указали в комментариях о потери контекста вызова. Что происходить на самом деле

setInterval(nissan.moveRight, 1000);

это эквивалент

let func = nissan.moveRight;

setInterval(func, 1000);

теперь вызов func() потерял контекст (nissan) так как вызывается напрямую. И this внутри func() уже window или null в зависимости от мода

Aziz Umarov
  • 22,567
  • 2
  • 10
  • 33
0

Потому что setInterval имеет синтаксис:

let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...)

где func|code - это функция или строка кода для выполнения. Обычно это функция. По историческим причинам можно передать и строку кода, но это не рекомендуется.


Надеюсь, понятно

viktor
  • 11