JS setInterval() работает только если расписать функцию целиком

Обучаюсь по книжке 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: "absolute",
        left: this.x,
        top: this.y
    });

    $("body").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); 

Ответы (2 шт):

Автор решения: Aziz Umarov

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

setInterval(nissan.moveRight, 1000);

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

let func = nissan.moveRight;

setInterval(func, 1000);

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

→ Ссылка
Автор решения: viktor

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

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

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


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

→ Ссылка