DEV Community

Discussion on: I Don't Use JavaScript Classes At All. Am I Missing Out on Something?

Collapse
 
aminnairi profile image
Amin • Edited

You can also create a function to keep track of your context and disminish the amount of side-effects using a more functional approach.

const createPositiveIntegerFrom = something => Math.abs((Number(something) || 0) | 0);

const Motorcycle = (brand = "Unknown", model = "Unknown", year = new Date().getFullYear(), mileage = 0, owners = 0, price = 0) => ({
  setBrand: newBrand => Motorcycle(String(newBrand), model, year, mileage, owners, price),
  setModel: newModel => Motorcycle(brand, String(newModel), year, mileage, owners, price),
  setYear: newYear => Motorcycle(brand, model, createPositiveIntegerFrom(newYear), mileage, owners, price),
  setMileage: newMileage => Motorcycle(brand, model, year, createPositiveIntegerFrom(newMileage), owners, price),
  setOwners: newOwners => Motorcycle(brand, model, year, mileage, createPositiveIntegerFrom(newOwners), price),
  setPrice: newPrice => Motorcycle(brand, model, year, mileage, owners, createPositiveIntegerFrom(newPrice)),
  brand,
  model,
  year,
  mileage,
  owners,
  price,
  isBrandNew: year === new Date().getFullYear() && mileage === 0 && owners === 0,
  isFirstHand: owners <= 1,
  needsServicing: [10000, 20000, 30000, 40000, 50000, 60000].includes(mileage),
  json: ({brand, model, year, mileage, owners, price})
});

let streetTriple = Motorcycle("Triumph", "Street Triple 765 R").setPrice(15000);

console.log(streetTriple.price);            // 15000
console.log(streetTriple.isBrandNew);       // true
console.log(streetTriple.isFirstHand);      // true
console.log(streetTriple.needsServicing);   // false

streetTriple = streetTriple.setOwners(1).setMileage(40000).setPrice(9500);

console.log(streetTriple.price);          // 9500, Yep... :(
console.log(streetTriple.isBrandNew);     // false
console.log(streetTriple.isFirstHand);    // true
console.log(streetTriple.needsServicing); // true

streetTriple = streetTriple.setOwners(2).setMileage(62000).setPrice(5500);

console.log(streetTriple.price);          // 5500 :')
console.log(streetTriple.isBrandNew);     // false
console.log(streetTriple.isFirstHand);    // false
console.log(streetTriple.needsServicing); // false

console.log(streetTriple.json);
// {brand: 'Triumph', model: 'Street Triple 765 R', year: 2021, mileage: 62000, owners: 2, price: 5500}
Enter fullscreen mode Exit fullscreen mode