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
thismuch: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
thisjumps out), etc...And of course, you can wrap that up in a helper:
Then
Option 3:
constructOMaticOf course, if we're going to define helpers, maybe we should go whole-hog:
...where
constructOMaticis:Now, you can use
thisto your heart's content within the callback. That fiddling withrvvs.objin thereturnat the end is to emulate the behavior ofnew(the result of anewexpression is the object created by thenewoperator unless the constructor function returns a non-nullobject reference, in which case that takes precedence).Object.createis 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: