Did you know that you can force a function to only act as a constructor? The following is an example of a Person
pseudo-class which can be defined with or without the new
keyword:
// Defines a person object.
function Person(firstName, lastName, age) {
// If called without parameters.
if(!arguments.length) {
// If this is a recursive call, allow the properties to now be defined.
if(arguments.callee.caller === arguments.callee) {
return this;
}
// If this is a non-recursive call, throw an error since the constructor
// can't be called without parameters.
else {
throw new Error("No parameters were specified for the Person object.");
}
}
// Allows make sure this function acts as a constructor.
var me = !(this instanceof arguments.callee) ? new Person : this;
// Define the properties.
me.firstName = firstName;
me.lastName = lastName;
me.age = age;
// Return a reference to the new Person instance.
return me;
}
// Define the prototypal functions.
Person.prototype = {
toString : function() {
return this.firstName + " " + this.lastName + " is " + this.age
+ " years old.";
}
};
One of the things that you may have noticed is the fact that I am throwing an error if the constructor is called without any arguments. If you don’t want that to happen, you can simply remove that else statement. Everything is probably pretty self explanatory.
The following are two examples which prove the above code actually works:
// Create an instance of a person without the "new" keyword.
var p = Person("Chris", "West", 23);
alert(p.firstName); // display "Chris"
alert(p instanceof Person); // display true
alert(p); // use toString() function
// Create an instance of a person with the "new" keyword.
var p = new Person("Tamara", "Thomas", 21);
alert(p.age); // display 21
alert(p instanceof Person); // display true
alert(p); // use toString() function.