Наследование классов в JavaScript

Пишу код где класс Truck наследует класс Car. Все ок, только v2.move() не корректно работает. Подскажите, пожалуйста, почему в терминале вместо модели машины пишет undefined? Даже если let v2 = new Truck() поменяю на let v2 = new Truck("Man") все равно не дает результата.

Машина undefined двигается со скоростью 80 км/час

class Car {
    model;

    constructor(model) {
        this.model = model;
    }

    move() {
        console.log(`Машина ${this.model} двигается со скоростью 80 км/час`);
    }
}

class Truck extends Car {
    weight;
    maxCargo;
    model;

    constructor(model, maxCargo) {
        super(model);
        this.maxCargo = maxCargo;
    }

    loadCargo(weight) {

        if (weight > 1000) {
            console.log("Этот грузовик не может перевозить более 1000кг груза");
        }
        else {
            this.weight = weight;
            console.log(`В грузовик загружено ${this.weight}кг.`);
        }
    }
}

let v1 = new Car("Mazda");
v1.move();

let v2 = new Truck();
v2.loadCargo(1500);
v2.move();


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

Автор решения: Daniil Loban

Чтобы хорошо понять что произошло, можно десахоризовать js классы в обычные функции, потому что мы не видим как именно создается класс.

Но когда мы смотрим на функцию конструктор мы четко видим последовательность действий.

В частности будет хорошо заметно что определение собственных свойств идет после вызова родительского конструктора и определения его свойств.

Я использую Object.defineProperty для большей наглядности того что происходит на самом деле ведь напиши я this.model; - ничего бы не произошло тут нет присваивания.

    function Car (model) {
        Object.defineProperty(this, "model", {
          enumerable: true,
          configurable: false,
          writable: true,
          value: model
        });

        this.move = function() {
            console.log(`Машина ${this.model} двигается со скоростью 80 км/час`);
        }
    }
    
    function Truck (model, maxCargo)  {
        Car.call(this, model) // вызов родительского конструктора
    
        Object.defineProperty(this, "weight", {
          enumerable: true,
          configurable: false,
          writable: true,
          value: undefined
        });
    
        Object.defineProperty(this, "maxCargo", {
          enumerable: true,
          configurable: false,
          writable: true,
          value: maxCargo
        });
        
        Object.defineProperty(this, "model", { // <= тут происходит перезапись
          enumerable: true,
          configurable: false,
          writable: true,
          value: undefined 
        });
    
        this.loadCargo = function(weight) {
            if (weight > 1000) {
                console.log("Этот грузовик не может перевозить более 1000кг груза");
            }
            else {
                this.weight = weight;
                console.log(`В грузовик загружено ${this.weight}кг.`);
            }
        }
    }
    
    let v1 = new Car("Mazda");
    v1.move();
    
    let v2 = new Truck("name");
    v2.loadCargo(1500);
    v2.move();

Решение

class Car {
    model;

    constructor(model) {
        this.model = model;
    }

    move() {
        console.log(`Машина ${this.model} двигается со скоростью 80 км/час`);
    }
}

class Truck extends Car {
    weight;
    maxCargo;

    constructor(model, maxCargo) {
        super(model);
        this.maxCargo = maxCargo;
    }

    loadCargo(weight) {

        if (weight > 1000) {
            console.log("Этот грузовик не может перевозить более 1000кг груза");
        }
        else {
            this.weight = weight;
            console.log(`В грузовик загружено ${this.weight}кг.`);
        }
    }
}

let v1 = new Car("Mazda");
v1.move();

let v2 = new Truck("new");
v2.loadCargo(1500);
v2.move();

→ Ссылка