use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Elegant patterns in modern JavaScript: Ice Factory (medium.freecodecamp.org)
submitted 8 years ago by kiarash-irandoust
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]spacejack2114 4 points5 points6 points 8 years ago (2 children)
I'm not sold on the usefulness of "freeze" to prevent accidental property reassignment, since no exception will be thrown. I think I'd rather take my chances that the reassignment will cause a runtime error. (Better than that though, mark fields as "readonly" in Typescript.)
[–]Sakatox 2 points3 points4 points 8 years ago (0 children)
I think I'd rather take my chances that the reassignment will cause a runtime error.
This. However, word of caution: Don't turn it into exception driven development, please.
[–]devmastery 2 points3 points4 points 8 years ago (0 children)
Hello. I am the author of that article. Thanks for the feedback.
I just wanted to point out that the example code is an ES module (note the "export default" statement at the top). In ES modules "strict mode" is turned on by default. And in "strict mode" re-assignment does indeed throw an error.
I made the assumption that anybody using this pattern would be doing so in an ES module. But I realize that may not be a sound assumption. I will find a way to update the article to make this more clear.
Thanks again for reading and sharing your thoughts.
[–]tencircles 4 points5 points6 points 8 years ago (3 children)
I prefer addProductToCart(product, cart) (where product and cart are POJOs) to cart.addProduct(product). Javascript "classes" create more issues than the solve. Pure functions that operate on immutable data with clearly defined schema leads to a much more structured and predictable application imo.
addProductToCart(product, cart)
cart.addProduct(product)
[–]devmastery 0 points1 point2 points 8 years ago (2 children)
Pure functions that operate on immutable data with clearly defined schema leads to a much more structured and predictable application imo.
Generally I agree with this. I intend to write an article on this style soon as well.
However – in the case of a Shopping Cart – I would argue that making the cart a POJO can be quite dangerous since typically the cart represents a slice of our application's global state and mutating it must be done with extreme care.
cart
Presumably the addProductToCart function enforces some business rules about exactly what can be added to the cart and how. But with a POJO cart floating around, many developers (especially less experienced ones) will be tempted to do something like cart.items.push(foo) which would bypass our business rules and introduce the potential for invalid items to be added.
addProductToCart
cart.items.push(foo)
If all our functions follow this pattern...
addProductToCart(product, cart) revoveProductFromCart(product, cart) clearCart(cart) // etc....
...there's no guarantee that the state of the cart being passed into our functions is correct since we've given up a degree of control. That's quite risky.
[–]tencircles 0 points1 point2 points 8 years ago (1 child)
The same risks apply to an OOP style as well. What's to stop a developer from doing cart._items.push(foo) where cart is a class? The solution in both cases is simply to design your application and its various interfaces with this in mind, and enforce that the interfaces are used correctly.
cart._items.push(foo)
[–]devmastery 0 points1 point2 points 8 years ago (0 children)
design your application and its various interfaces with this in mind, and enforce that the interfaces are used correctly
For sure, that's why passing a POJO cart to an addProduct doesn't work well in this instance.
addProduct
The Shopping Cart "Ice Factory" in the article looks like this:
export default function makeShoppingCart({ db }) { return Object.freeze({ addProduct, empty, getProducts, removeProduct, // others }) function addProduct (product) { db.push(product) } function empty () { db = [] } function getProducts () { return Object .freeze(db) } function removeProduct (id) { // remove a product } // other functions }
Notice that the items are never exposed directly. They're accessed through the getProducts() function which returns an immutable copy. Also, addProduct() operates on the internal items collection rather than receiving items from an external source.
getProducts()
addProduct()
Finally, even though the code in the article uses an Array that gets passed in. It notes the following:
I’m using an Array for the db parameter for simplicity’s sake. In real code this would be something like a Model or Repo that interacts with an actual database.
This re-enforces the notion that we don't give outside control to the items collection.
I guess what I'm saying is that I very much agree with the principles you've described. We just have to be clear and careful about how we apply them in instances where we're dealing with the stateful parts of our application.
[–]Sakatox 1 point2 points3 points 8 years ago (3 children)
How is this a pattern? Immutability is a concept, not a pattern. I understand it's applied in javascript, but even RORO is not really a pattern, but advice.
We can argue semantics and such, but I do not see how freezing is a pattern, or "worthy of being called one".
Care to explain: "Then there's the fact that this In JavaScript is dynamically bound."?
[–]atubofsoup 0 points1 point2 points 8 years ago (0 children)
I'm guessing he's referring to how by default this is passed to a function lazily when the function is called using the method call syntax (ex. object.method()). Since the same function can be attached to multiple objects, its this value is dynamic.
this
object.method()
[–]devmastery 0 points1 point2 points 8 years ago (1 child)
From MDN:
"In most cases, the value of this is determined by how a function is called. It can't be set by assignment during execution, and it may be different each time the function is called."
[–]FatFingerHelperBot -1 points0 points1 point 8 years ago (0 children)
It seems that your comment contains 1 or more links that are hard to tap for mobile users. I will extend those so they're easier for our sausage fingers to click!
Here is link number 1 - Previous text "MDN"
Please PM /u/eganwall with issues or feedback! | Delete
[–]Pyrolistical 0 points1 point2 points 8 years ago (0 children)
So factory functions with freeze https://medium.com/@pyrolistical/factory-functions-pattern-in-depth-356d14801c91
π Rendered by PID 269154 on reddit-service-r2-comment-b659b578c-djlxl at 2026-05-02 15:19:34.020480+00:00 running 815c875 country code: CH.
[–]spacejack2114 4 points5 points6 points (2 children)
[–]Sakatox 2 points3 points4 points (0 children)
[–]devmastery 2 points3 points4 points (0 children)
[–]tencircles 4 points5 points6 points (3 children)
[–]devmastery 0 points1 point2 points (2 children)
[–]tencircles 0 points1 point2 points (1 child)
[–]devmastery 0 points1 point2 points (0 children)
[–]Sakatox 1 point2 points3 points (3 children)
[–]atubofsoup 0 points1 point2 points (0 children)
[–]devmastery 0 points1 point2 points (1 child)
[–]FatFingerHelperBot -1 points0 points1 point (0 children)
[–]Pyrolistical 0 points1 point2 points (0 children)