0

Following constructor function and log code is given ...

function Car(brand, year, model, color, utilidad) {
  this.brand = brand;
  this.year = year;
  this.model = model;
  this.color = color;
  this.utilidad = utilidad;
  this.useFor = (prmt) => {
    this.utilidad.push(prmt);
  }
};

const toyota = new Car("Toyota", 2021, "Prado", "Red", "city");
toyota.useFor('mountain');

console.log(toyota);

Instead of getting the expected log data the code breaks with following message ...

TypeError: "this.utilidad.push is not a function"

Why does this happen?

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
  • 1
    `utilidad` [is not an array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) – B001ᛦ Oct 28 '21 at 16:59
  • The OP did not build a prototype but was implementing a function which is intended to be used as constructor in order to create `Car` instances. On top the OP is initializing `toyota` with a wrongly typed `utilidad` argument which is supposed to be an array and not a string in oder to allow the `useFor` method to later push into the object's own `utilidad` property. – Peter Seliger Oct 28 '21 at 18:03

2 Answers2

1

because *.push() use to insert data in array, but you put string "city" on default parameter;

KangJeki
  • 173
  • 3
0

From the above comment ...

"The OP did not build a prototype but was implementing a function which is intended to be used as constructor in order to create Car instances. On top the OP is initializing toyota with a wrongly typed utilidad argument which is supposed to be an array and not a string in oder to allow the useFor method to later push into the object's own utilidad property."

Thus a refactored Car implementation internally might use initial or default values for omitted argument values. It might introduce some formal type checking in order to not break from TypeErrors due to wrongly provided argument types. And in addition to the tasks of assigning the arguments as own properties to an object it does implement its only method at the constructor function's prototype ...

function Car(
  brand = 'unknown',
  year = 'not provided',
  model =  'unknown',
  color = 'not provided',
  utilidad = [],
) {
  return Object.assign(this, {
    brand,
    year,
    model,
    color,
    utilidad: Array.isArray(utilidad)
     ? utilidad
     : [utilidad],
  });
};
Car.prototype.useFor = function useFor (value) {
  this.utilidad.push(value);
};


const dummy = new Car();
const toyota = new Car('Toyota', 2021, 'Prado', 'Red', 'city');

dummy.useFor('test field');
toyota.useFor('mountain');

console.log({ dummy, toyota });
.as-console-wrapper { min-height: 100%!important; top: 0; }

The next iteration might introduce class syntax and a constructor which expects a single config or options argument ...

class Car {
  constructor({
    brand = 'unknown',
    year = 'not provided',
    model =  'unknown',
    color = 'not provided',
    utilidad = [],
  }) {
    Object.assign(this, {
      brand,
      year,
      model,
      color,
      utilidad: Array.isArray(utilidad)
       ? utilidad
       : [utilidad],
    });
  }
  // prototype method(s)
  useFor(value) {
    this.utilidad.push(value);
  }
}


const dummy = new Car({});
const toyota = new Car({
  brand: 'Toyota',
  year: 2021,
  model: 'Prado',
  color: 'Red',
  utilidad: 'city',
});

dummy.useFor('test field');
toyota.useFor('mountain');

console.log({ dummy, toyota });
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37