Acabo de empezar a usar las clases de JavaScript y tengo una pregunta rápida. En el siguiente ejemplo, quiero asegurar/convertir ciertas propiedades para que sean numéricas cuando creo la clase. Por ejemplo, si el usuario ingresa "$ 10.50" para el precio unitario, quiero que la clase solo tenga 10.50 para que funcione la función total. Estoy seguro de que esto se puede hacer con un getter/setter pero no puedo entender cómo implementarlo.
<form name="orderform"> order date: <input name="order_date" value="" type=text> <br>item_name: <input name="item_name" value="" type=text> <br>unit_price: <input name="unit_price" value="" type=text> <br>quantity: <input name="quantity" value="0" type=text> </form> class OrderItem { constructor( order_date, item_name, unit_price, quantity, ) { this.order_date = order_date; this.item_name = item_name; this.unit_price = unit_price; this.quantity = quantity; } get total() { return this.unit_price * this.quantity; } } const orderitem1 = new OrderItem(); function GetNumber(val) { if (typeof val !== 'undefined') { return Number(val.replace(/[^0-9.-]+/g, "")); } else { return 0; } } function getOrder() { $("#orderform").serializeArray().map(function(x){orderitem1[x.name] = x.value;}); var total = orderitem.total; //doesn't work if they enter '$10.50' //...do stuff here with the orderitem1 class.... }En lugar de crear el artículo de OrderItem y luego actualizar sus valores en getOrder , podría crear el artículo de pedido en el acto.
El fragmento a continuación crea una instancia de un artículo de pedido a partir de los datos del formulario en el envío y analiza los valores numéricos en el constructor utilizando su función GetNumber existente.
También podría considerar cambiar el tipo de entrada de 'texto' a 'número' para esas entradas, lo que (en su mayoría) evitaría que los usuarios ingresen $ en primer lugar.
// get a reference to the form const form = document.querySelector('form[name=orderform]'); // add an onsubmit handler form.addEventListener('submit', (e) => { // stop the form from submitting e.preventDefault(); // convert the form's inputs into a key-value mapping, eg { quantity: "12", unit_price: "$10.50", ... } const data = new FormData(e.target); const config = [...data.entries()].reduce((acc, [key, value]) => ({...acc, [key]: value}), {}) // instantiate an OrderItem from the config const orderItem = new OrderItem(config); // do whatever you need to do with it console.log(orderItem.total); }) class OrderItem { constructor({ order_date, item_name, unit_price, quantity, } = {}) { this.order_date = order_date; this.item_name = item_name; this.unit_price = GetNumber(unit_price); this.quantity = GetNumber(quantity); } get total() { return this.unit_price * this.quantity; } } function GetNumber(val) { if (typeof val !== 'undefined') { return Number(val.replace(/[^0-9.-]+/g, "")); } else { return 0; } } <form name="orderform"> order date: <input name="order_date" value="" type=text> <br>item_name: <input name="item_name" value="" type=text> <br>unit_price: <input name="unit_price" value="$10.50" type=text> <br>quantity: <input name="quantity" value="1" type=text> <button>Get Order</button> </form>Si por alguna razón necesita poder cambiar los valores del artículo de pedido después de crear una instancia, puede hacerlo en un getter o setter. (Pero, en términos generales, la inmutabilidad es A Good Thing™).
class OrderItem { set unit_price(p) { // needs a different internal name to avoid recursion this._unitPrice = toNumber(p); } get unit_price() { return this._unitPrice; } } const toNumber = v => Number(`${v}`.replace(/[^0-9.]/g, '')); const item = new OrderItem(); item.unit_price = '$10.50'; console.log(item.unit_price);