Astrotim
Astrotim

Reputation: 2172

Factory functions vs Object.create - JavaScript - when to use which

I have been reading much about object composition in JavaScript and the advantages of this pattern over the 'class' pattern. I have seen examples of the composition that demonstrate using Object.create() to create new objects and other examples that demonstration using factory functions that return objects.

Object.create example:

var Component = {
  init: function() {
    // do stuff
  }
};

var button = Object.create(Component);

button.init();

Factory function example:

var ComponentFactory = function() {
   return {
     init: function() {
       // do stuff
     }
  }
}

var button = ComponentFactory();

button.init();

I understand that factory functions are intended for abstracting away complexity involved in creating objects, however I am trying to understand if there is any practical difference between Object.create() and a function which returns an object.

Upvotes: 5

Views: 1957

Answers (3)

Achesa Makhambala
Achesa Makhambala

Reputation: 67

As other have mentioned, Object.create() allows you to create objects that have some relationship, while Function factories don't. I would actually argue that Object.create is a form of factory function, only that the function is bound to creating objects with the same properties. Consider these two scenarios:

Object.create:

const Staff = {
    setUp: function(name, idno){
        this.name = name;
        this.idno = idno;
        this.office = "Unallocated"
        this.category = "Staff";
        this.accomodation = ""
            
        }
    };

    james = Object.create(Staff);
    james.setUp("James Black", 1)
    console.log(james.name) //James Black
    console.log(james.idno) //1

//Now let's assume that we want to change something about the 10,000 staff that //we recruit and sack every year. One condition is that all our staff are 20 //years old.

we simply say*/

    Staff.age = 20
    console.log(james.age)//20

As you can see, you can change the property of all members of a group by simply changing the parent object. If however you are using a function factory that simply creates unique objects each time, you won't be able to do this.

Upvotes: 0

DarkKnight
DarkKnight

Reputation: 5934

Factory functions create objects with its own properties, Object.create creates objects with assigned prototype.

In your example, every object created by ComponentFactory has its own init (reference to different location in memory), Object.create(Component) creates objects reference to the same prototype(Component)

Object.create costs less space/memory, since it doesn't create properties. Use this for the common part of objects.

Factory functions are more flexible, can create objects with initial data, and local variables in closures. Use this for custom part of objects.

const Component = {init() {}}
const x = Object.create(Component)
const y = Object.create(Component)

console.log(x.init === y.init) //true


function createComponent(data) {
  return {
    init() { return data }
  }
}

const p = createComponent('a')
const q = createComponent('b')
console.log(p.init === q.init) //false
console.log(p.init()) //a
console.log(q.init()) //b

Upvotes: 6

Maciej Sikora
Maciej Sikora

Reputation: 20132

I. Object.create

Object.create create object from prototype given in attribute, so if We check hasOwnProperty on object created from Object.create we will see that it has no properties ( every one is in his prototype ).

So every object created by Object.create(SomeObj) is linked with the same prototype, this has some consequences, for example complex objects in prototype can be changed on every instance and change is visible on other instances.

Conclusion - Object.create is something similar to inheritance.

Example code to show what I am talking about:

var obj={

    complexProp:{
        name:"John",
        surname:"Doe"
    },
    hello:function(){
    
      console.log("Hello "+this.complexProp.name+" "+this.complexProp.surname);

    }

};

var objA=Object.create(obj);
var objB=Object.create(obj);

console.log(objA.hasOwnProperty("complexProp"));//false

objA.complexProp.surname="Smith";//change in objA

objB.hello();//so we see that change is also in objB

II. Factory

Second example is creating objects on the fly, so every object is new instance, no connection between objects. Second solution also give us closure , so we can create some private variables or functions visible only for our object. Private variable usage:

var ComponentFactory = function(surname) {

   var name="John";//local variable visible for object

   return {
     init: function() {
     // do stuff
     //variable name is visible in object
     //variable surname is also visible from object

     }
  }
}

Upvotes: 2

Related Questions