How does a constructor that just returns an object literal work?
Both of the following constructor functions work the same (as far as I have been able to tell) when I invoke them as:
var x2z = new xyz('ralph');
whether I write a constructor function like this:
function xyz(name) {
return {
name: name,
x:1,
get y() {return this.x+1},
get z() {return this.y+1}
}
}
or if I had declared it:
function xyz(name) {
this.name = name;
this.x = 1;
Object.defineProperties(this, {
"y": {"get": function() {return this.x+1}}
}),
Object.defineProperties(this, {
"z": {"get": function() {return this.y+1}}
})
}
The second form is the one that is documented everywhere. But why does the first one work? Is the new keyword just ignored and the object literal returned?
How are the two related to one another? If someone could point me to a reference that would be great; I can find a lot of stuff on objects but I haven't found anything on the first form.
I put together a simple jsperf and the literal version is slightly faster, but not enough to use it if it's just an oddity. (jsperf example). But it seems more straightforward than the more typically used constructor that refers to "this".
MDN has very nice documentation about "new": https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created [initially] is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
why does the first one work?
Notice that the first one does not create instances which inherit from xyz.prototype
.
Is the new keyword just ignored and the object literal returned?
Yes. If the constructor return
s an object, that will be returned by the new
operator instead of the instance that was constructed and passed to the constructor as this
. For details, see What is the 'new' keyword in JavaScript? or MDN.
However, notice that if you use the first, you should omit the new
(to make clear it's a factory function), and if you use the second you should capitalize your constructor to Xyz
.