Core JavaScript · 8 of 9
Putting it together: here's a small order-total service in the old style, then the same behavior rebuilt as an ES module using the patterns from this path.
namespace Orders {
export class OrderService {
private items: { price: number; qty: number }[] = [];
add(price: number, qty: number): void {
this.items.push({ price, qty });
}
total(): number {
let sum = 0;
for (const item of this.items) {
sum += item.price * item.qty;
}
return sum;
}
}
}
const service = new Orders.OrderService();
service.add(10, 2);
service.total(); // 20
// order-service.js
const itemTotal = (item) => {
return item.price * item.qty;
};
export const createOrder = () => {
let items = [];
return {
add(price, qty) {
items = [...items, { price, qty }];
},
total() {
return items.reduce((sum, item) => sum + itemTotal(item), 0);
},
};
};
// usage
import { createOrder } from "./order-service.js";
const order = createOrder();
order.add(10, 2);
order.total(); // 20
order-service.js is scoped by the file, exported explicitly, with no global merging.items is private by scope; there's no this to lose track of.itemTotal is a small unexported function, not a private method tied to an instance.add replaces items with a new array via spread rather than pushing into the existing one.Nothing here is a rule to apply everywhere — but it's the default worth reaching for first, before a class.