Assigning the same properties to every new object gets tedious. A constructor function puts that setup in one place. It is an ordinary function used to create and initialize an object when called with `new`. section 7.2 section 4.2.3
What changes when you call it with `new`?
- A new empty object is created and supplied to the function as `this`. Assignments such as `this.skulk = ...` initialize that object. section 4.2.3
- The resulting object uses the function’s `prototype` object as its prototype, so methods placed there are accessible to it. section 7.2
- A returned primitive does not replace the new object. An explicitly returned object does—potentially discarding the object initialized through `this`. section 4.2.3
Listing 4.7. Using a constructor to set up common objects
function Ninja() { #A
this.skulk = function() { #A
return this; #A
}; #A
} #A
var ninja1 = new Ninja(); #B
var ninja2 = new Ninja(); #B
assert(ninja1.skulk() === ninja1, #C
"The 1st ninja is skulking"); #C
assert(ninja2.skulk() === ninja2, #C
"The 2nd ninja is skulking"); #C
Two calls to `new Ninja()` produce separate objects. Each receives a `skulk` method, and calling that method returns its own object. section 4.2.3
Listing 7.2. Creating a new instance with a prototyped method
function Ninja(){} #A
Ninja.prototype.swingSword = function(){ #B
return true; #B
}; #B
const ninja1 = Ninja(); #C
assert(ninja1 === undefined, #C
"No instance of Ninja created."); #C
const ninja2 = new Ninja(); #D
assert(ninja2 && #D
ninja2.swingSword && #D
ninja2.swingSword(), #D
"Instance exists and method is callable." ); #D
Compare `Ninja()` with `new Ninja()`: the ordinary call returns `undefined`, while the constructed object can call a method assigned to `Ninja.prototype`. section 7.2
The practical rule is to notice the call site: the same function behaves differently without `new`. A constructor function also differs from `new Function(...)`, which creates a function from strings rather than creating an object instance. section 4.2 section 4.2.3
