What difference is there in JavaScript between a constructor function, and function returning object which is invoked as a constructor?

constructor, function, javascript

Solution

In short:

new something2() instanceof something2 === false

Relatedly, if you extend your example to use the prototype property

Something.prototype.method = function () { };
something2.prototype.method = function () { };

you will find that the prototype is not inherited in the latter case:

typeof (new Something()).method === "function"
type (new something2()).method === "undefined"

The real answer is that you are tapping into entirely different underlying machinery. Calling with `new` invokes the [[Construct]] mechanism, which involves setting the [[Prototype]] property according to the `.prototype` property of the constructor.

But a funny thing happens in steps 8--10 of the [[Construct]] algorithm: after setting up a new, empty object, and then attaching its [[Prototype]], it does a [[Call]] to the actual constructor, using this new empty-plus-prototype object as `this`. And then, in step 9, if it turns out that that constructor returned something---it throws away that prototypally-bound, passed-as-`this` object that it spent all that time setting up!

Note: you can access an object's [[Prototype]] (which is different from a constructor's `.prototype`) with `Object.getPrototypeOf`:

Object.getPrototypeOf(new Something()) === Something.prototype // steps 5 & 6
Object.getPrototypeOf(new something2()) === Object.prototype // default

To answer some meta-questions:

- No, don't capitalize `something2`, since it is a factory function and not a constructor. If something is capitalized, it is expected to have constructor semantics, e.g. `new A() instanceof A`.

- If you're worried about the danger of clobbering the global namespace, you should start using strict mode, by putting `"use strict";` at the top of your files. One of the many nice cleanups of strict mode is that `this` defaults to `undefined`, not the global object, so e.g. calling a constructor without `new` will result in errors the moment the constructor tries to attach properties to `undefined`.

- Factory functions (aka the "closure pattern") are in general a reasonable substitute for constructors and classes, as long as you are (a) not using inheritance; (b) not constructing too many instances of that object. The latter is because, in the closure pattern, you attach a new instance of every method to every newly-created object, which is not great for memory usage. The biggest payoff, IMO, of the closure pattern is the ability to use "private" variables (which are a good thing, and don't let anyone tell you otherwise :P).

Problem

I know this is not the recommended way of doing it, but if I declare the following functions, and then invoke them as constructors, what will be the difference (if any) between the resulting objects? ``` function Something() { this.foo = "bar"; } function something2() { var that = {}; that.foo = "bar"; return that; } var x = new Something(); var y = new something2(); var z = something2(); ``` I.e. what will differ between `x`, `y` and `z` here? Wouldn't `something2` be a much better way of writing the constructor, since whether you use `new` or not will not affect the result of the function? BTW should `something2` be capitalized here? (I assume not since Crockford is so adamant on the capitalization, for functions will clobber the global namespace...)

Original source