Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two ways of constructing an object in Javascript

function Person(age,name){
    this.name = name;
    this.age  = age;
    this.speak = function(){...}
}

function Person(age,name){
    var p = {}
    p.name = name;
    p.age = age;
    p.speak = function(){...}
    return p;
}

The only difference I see is that using the first one you must call with new to let the language know its constructing a new object, is it essentially just constructing an object where 'this' refers to the new object being created??

i.e same as doing this.

{
   age: 12,
   name: "mark",
   speak: function(){...}
}

where as the second returns an object so you can just write

Person(12,"mark")

instead of

new Person(12,"mark")

So I guess my question is, is there anything wrong with using the second version and are the differences I stated correct and are they the only differences between the two?

like image 245
Koborl Avatar asked Apr 02 '15 02:04

Koborl


1 Answers

The first one:

function Person(age,name){
    this.name = name;
    this.age  = age;
    this.speak = function(){...}
}
  1. Is a named constructor function.
  2. Will work properly with instanceof Person
  3. Is easier to do mixins or classic Javascript inheritance with
  4. Could use the prototype for methods which may consume less memory or be faster to construct an object if there are lots of methods
  5. Could also be designed to work without requiring new.
  6. Is more akin to how the new ES6 class and extends syntax works which is likely how a lot of Javascript will be written in the future.

The second one:

function Person(age,name){
    var p = {}
    p.name = name;
    p.age = age;
    p.speak = function(){...}
    return p;
}
  1. Is a factory function. It creates a generic object, assigns properties to it and then returns the object.
  2. It could be inherited from, but not in a classic way only by another factory function that knows how this object works. Some types of inheritance of mixins are not as doable with this structure.
  3. Will not work with instanceof.
  4. Does not and cannot use the prototype for methods.
  5. Could be called with new and would still work (the system-created new object would just be discarded).
  6. Can create any kind of object. It can even branch based on the arguments passed or environment and create a different kind of object based on some logic. Technically you can do this with the first style too, but it's inefficient because the interpreter creates a specific type of object and then you would return something else causing the original object that was created to then be garbage collected. So, if you're going to create multiple different kinds of objects, the second method would be more efficient at that.

Outside of these differences, the two will mostly function the same and there is nothing technically "wrong" with either method.

There are advocates for both styles of programming in Javascript and some would say there are situations where one is more appropriate than another and vice versa. I'd suggest you build a couple subclasses for this object to flush out some more of the programming differences because the subclasses will also work differently.


If you want to search for other articles on the topic, this is basically a "constructor function vs. a factory function in Javascript" which will sometimes stray into the argument for/against using the .prototype, but also tends to cover your topic too.

Here's are some articles on that specific topic (which cover a gamut of opinions):

JavaScript Constructor Functions Vs Factory Functions

Javascript object creation patterns

In defense of JavaScript’s constructors

Constructor function vs Factory functions

Factory constructor pattern

Some Useful JavaScript Object Creation Patterns

Constructors Are Bad For JavaScript

Constructors vs factories

like image 171
jfriend00 Avatar answered Oct 10 '22 15:10

jfriend00