related to How can I call a javascript constructor using call or apply?
but not the same, I'm trying to apply the SO answers to John Resig's forcing a constructor when not called properly.
function User(first, last){
if ( !(this instanceof User) )
// the line I want to replace, or remove the redundancy from:
return new User(first, last);
this.name = first + " " + last;
}
var name = "Resig";
var user = User("John", name);
assert( user, "This was defined correctly, even if it was by mistake." );
assert( name == "Resig", "The right name was maintained." );
The target line of code means every time the constructor changes, someone has to remember to change the internal self-call arguments. I've already had a project trip over this issue 3 times in the last 3 days.
All the examples in the linked question talk about passing the constructor
, but what is the constructor
in this case? It's not even finished being defined yet.
but so far all attempts do not pass the test, or throw a stackoverflow.
How do I make sure the constructor being called results in something that responds properly to instanceof User
even when called without the new
keyword, while eliminating the repetition of argument parameters?
Some options for you, all using
Object.create
:Option 1:
Of course, all of that logic doesn't have to be repeated for every constructor function you create, you can use a helper function:
then
Option 2: Don't use
this
much:As you can see, this is a lot simpler, but if you really like your syntax highlighting (seriously, I have a client to whom it really matters that
this
jumps out), etc...And of course, you can wrap that up in a helper:
Then
Option 3:
constructOMatic
Of course, if we're going to define helpers, maybe we should go whole-hog:
...where
constructOMatic
is:Now, you can use
this
to your heart's content within the callback. That fiddling withrv
vs.obj
in thereturn
at the end is to emulate the behavior ofnew
(the result of anew
expression is the object created by thenew
operator unless the constructor function returns a non-null
object reference, in which case that takes precedence).Object.create
is an ES5 feature found on all modern browsers, but the single-argument version of it used above can be shimmed for out-of-date browsers: