Конструктор, дефолтные значения

Как установить дефолтные значения в конструкторе, которые потом можно перезаписать при создании экземпляра класса?
Допустим я не установил название танка и скрипт выводил бы “no name”. И как дефолтные значения добавить в класс?

class Tank {
    constructor(options) {
        this.name = options.name
        this.country = options.country
        
        console.log(this.name + ' ' + this.country)
    }
}
    
let tank = new Tank({
    name: "t-34",
    country: "rus"
})
 
let default = {
    name: "no name",
    country: "no country"
}

Использовать деструкцию.
Вот отличная статья с важными замечаниями по деструкции объекта и заданию значений по умолчанию у аргумента функции

1 симпатия

Есть несколько вариантов как добиться желаемого поведения. Для разных ситуаций (в зависимости от количества классов, способов организации кода, наличие отсутствие наследования, пишешь на новом или старом js, или вообще на тайпскрипте) подойдут разные. Смотри что тебе больше понравится.

Первый вариант - держать где-то объект с дефолтными опциями. Когда конструируется инстанс - копировать все дефолтные свойства и перекрывать их теми что пользователь мог передать. options = {} запишет в options пустой объект если когда вызывается без аргументов.

const defaultOptions = {
    name: "no name",
    country: "no country"
}

class Tank {
    constructor(options = {}) {
    	options = Object.assign({}, defaultOptions, options)
        this.name = options.name
        this.country = options.country
        
        console.log(this.name + ' ' + this.country)
    }
}
    
let tank = new Tank({
    country: "rus"
})
 
console.log('tank', tank)

Второй вариант - положить свойства в прототип, а те, с которыми конструируется инстанс, положить в инстанс класса. Получится что при обращении к свойству оно будет искаться по цепочке прототипов, находясь или в инстансе или в прототипе (там будут дефолтные).

class Tank {
    constructor(options) {
    	Object.assign(this, options)
        
        console.log(this.name + ' ' + this.country)
    }
}

Tank.prototype.name = 'no name'
Tank.prototype.country = 'no country'
    
let tank = new Tank({
    country: "rus"
})

console.log(tank.name, tank.country)

Третий - использовать ленивость оператора ||. Тут будут нюансы если значения параметров могут быть 0, "", null итд (т.е. falsy типов).

class Tank {
    constructor(options) {
        this.name = options.name || 'no name'
        this.country = options.country || 'no country'
        
        console.log(this.name + ' ' + this.country)
    }
}
    
let tank = new Tank({
    name: "t-34",
})

Выше @devSkripatch дал годную статью. Это идиоматический подход для свежих версий javascript.

Я бы выбрал или первый вариант или то как посоветовал @devSkripatch.

1 симпатия

Опции можно опустить.

class Tank {
    constructor({ name, country } = defaultTankOptions) {
        this.name = name ?? defaultTankOptions.name;
        this.country = country ?? defaultTankOptions.country;
        console.log(this.name + ' ' + this.country);
    }
}
 
let tank = new Tank({
    name: "t-34",
    country: "rus"
});
 
let defaultTankOptions = {
    name: "no name",
    country: "no country"
};
 
console.log(tank);
console.log(new Tank({ name: "force" }));