Factory Functions are the Preferred way to create JS Objects

There are a bunch of ways to create objects in JS. The language has undergone so much change that you could have a bunch of JS developers who all do it different ways. I have my reasons for preferring factory functions and object composition, and I will try and show why I think they are worth using.

Avoid ‘this’ and ‘new’, because there are alternatives

Constructor functions and Classes are constructs generally worth avoiding in JS because they come with the ever confusing ‘this’ keyword to handle, and they don’t seem to have a compelling use that can’t be done another way. They imitate the constructs of other languages but don’t take full advantage of the strength present in JS.
Sometimes I end up using ‘this’ in object literals or if a library requires it, I just try not to put myself in situation where I will be throwing it around because it always ends up being confusing somewhere.

When I need to store/share data, I use closures

Closures can attach data to objects or functions with no question whatsoever as what they will have access to. It does not matter how the object or function gets passed or assigned so long as the closure was set up correctly in the first place. There is no trying to sort out binding precedence like with ‘this’.

Composing objects with Object.assign() or { } is simple

No super, constructors, or any confusion about inheritance chains. Perform any operations you need to like passing settings via closure, then join the objects together. If you want to extend the object, you can do that as well.

For examples, look at my node libraries

I have several node libraries that make extensive use of these techniques, so those are one place to look for more examples.
File Manipulator
MongoDB Toolset
Stream Library

Setting up a factory function

A factory function is just a function that returns an object or function configured by some arguments you pass it. If it just returns a function I would call it a closure, but returning an object it is an object factory; hence factory function.

const slider = (state) => {
 state.speed = 0
 return ({  
  push: (effort) => {
   state.speed = (effort * state.length/100 + state.slipness/2)
   return (effort * (state.length/100 + state.slipness/2))  
  },
  slide: (time) => {  
   return (state.speed * Math.sqrt(time))  
  }
 })
}

const climber = (state) => ({  
  climb: (effort, grade) => {  
     return (effort - (state.length/100 + state.slipness/2) - grade/2)  
  },
})

let sl = slider({length: 150, slipness: 6})
let cl = climber({length: 205, slipness: 4})

Because it uses closure, no need for ‘this’
The state variable holds data that is needed by the object, and it will not change thereafter. You don’t have to be concerned with how the context for the object might change.

Use another factory to combine objects

This will take the previous two factory functions and combine their outputs into a single object with shared state/functionality. You call the factory functions and combine the outputs either with Object.assign( ) or spread operators { …obj1, …obj2 }

// Do it using Object.assign()
var ski1 = (length, width) => {  
  let state = {  
    length: length,  
    width: width,  
    slipness: 5,  
  }
  return Object.assign({},  
    slider(state),   
    climber(state),  
  )
}
xc1 = ski1(130, 6)  

//Same thing, but use new JS object operators
var ski2 = (length, width) => {  
  let state = {  
    length: length,  
    width: width,  
    slipness: 5,  
  }
  let sl1 = slider(state)
  let cl1 = climber(state)
  return { ...sl1, ...cl1 } 
}
xc2 = ski2(170, 7)  

Making data persistent

This is just a simple counter example. It takes an argument to set the maximum for the counter and the statement to output when the maximum is reached. The returned object will then always have access to those values in the closure and you can make differnt versions of the counter.

const counter = max => statement => {  
  var n = 0;  
  return () => {  
    n++;  
    if((n % max) === 0){  
      console.log('Counted ',n,statement,'\nat ',new Date())  
    }
  }
}

Actual case where I used this pattern; a database interaction tool

This is a library that connects to and allows operations on a mongodb database. It sets up a connection, accesses a db and collection, and then passes that along to all the sub function which can then use it.
Each instance is bound to a collection
Each returned object is bound to a collection and all the commands issued are specific to that collection. If you want to interact with a different collection, you just call the mongoMaker command again with a different config and it will return an object specific to that config.

const commands = require('./src/commands')

const settings_required = ["urldb","database"]
const mongoMaker = async function(inSettings){
  checkset.checkSettings(settings_required)(inSettings);
  let settings = R.clone(inSettings)
  let mongoClient = await db.mongoClient(settings.urldb);
  let Db = await db.Db(mongoClient, settings.database);
  let collection = await db.collection(Db);
  const command = db.command(Db);
  return Object.assign(
    {},
    {checkExists: commands.checkExists(collection)},
    {closeConnect: db.closeConnect(mongoClient)},
    {find: commands.find(collection) },
    {findOne: commands.findOne(collection) },
    {aggregate: commands.aggregate(collection) },
    {insertMany: commands.insertMany(collection) },
    {deleteMany: commands.deleteMany(collection) },
    {Db: Db},
    {collection: collection},
  )
}

Extending an object

This is how to go about this generally. This is not a pattern I have used much, but I could see how it could be useful if you can’t create an object all at once.

let addon = (add, base) => {
  return({
    ...base,
    ...add 
  })
}

Factory functions: My goto method for object creation

There is generally a strong impulse to create inheritance chains and gravitate toward anything called a class for iheritance, but JS has really effective ways to create objects without needing to do this. Factory functions can use a combination of closures and object creation to link together sets of objects/functions and achieve resulting objects that suit the same needs and seem to do it better.

Objects can be loosely coupled and composed arbitrarily

No need for inheritance heirarchies when composing objects. Objects and functions with well defined, independent purposes can be created and then composed into a greater object. If pieces are changed/added/removed it should not matter, because they were independent to begin with. This encourages keeping objects loosely couple and single purpose, so I think this pattern not only works well but also encourages good code design.