Hi Steve,
First, thank you for the tutorial/hints in javascript/constructor-vs-prototype.html
I did want to point out one thing, though. You basically spend lines 215 to 255 demonstrating why defining this.company
within the Employee
constructor is "the WRONG way to do it," however it seems like you're missing the broader context for that technique.
So, you seem to imply that company
should be a "class" variable, with a single value shared by all instances of Employee
. In that case, yes, declaring Employee.prototype.company
after the definition for Employee
is one way to make that happen.
On the other hand, what about the variables firstName
and lastName
? In the example you add these variables to each of the Employee
objects after they have been instantiated, which indicates that an instance of Employee
may or may NOT have a firstName
or lastName
. Yet, if you wanted to ensure that every Employee
had a firstName
and lastName
, as well as indicate that the value of these variables is independent from one instance to another (i.e. "instance" variables), then using this
to define these vars within the Employee
constructor is the optimal technique:
var Employee = function( firstName, lastName )
{
this.firstName = firstName || "First Name";
this.lastName = lastName || "Last Name";
}
Also, getting back to Employee.prototype.company
, you can use it within the constructor function and still achieve a "class" level variable, the value of which is shared by all instances, as in:
var Employee = function( firstName, lastName )
{
Employee.prototype.company = "EA"; // overwrites prototype 'company' each time constructor is called
this.firstName = firstName || "First Name";
this.lastName = lastName || "Last Name";
}
If you change Employee.prototype.company
after the object has been created, that object's company
will change as well. Unless you specifically assign a value to dude.company
after you instantiate a new Employee
(in this case dude
), that object's company
will be referenced up the prototype chain. So, using the above constructor you can:
var steve = new Employee("Steve", "Kwan");
var andrew = new Employee("Andrew", "Wilson");
console.log( steve.firstName +"\n"+ steve.lastName +"\n"+ steve.company );
console.log( andrew.firstName +"\n"+ andrew.lastName +"\n"+ andrew.company );
Employee.prototype.company = "Electronic Arts";
console.log( steve.firstName +"\n"+ steve.lastName +"\n"+ steve.company );
console.log( andrew.firstName +"\n"+ andrew.lastName +"\n"+ andrew.company );
and see:
Steve
Kwan
EA
Andrew
Wilson
EA
Steve
Kwan
Electronic Arts
Andrew
Wilson
Electronic Arts
The only problem here is that if a new object is created Employee.prototype.company
will be reset to EA. Here's how a way to deal with that:
/* Cont'd */
var Employee = function( firstName, lastName )
{
Employee.prototype.company = Employee.prototype.company || "EA";
this.firstName = firstName || "First Name";
this.lastName = lastName || "Last Name";
}
Employee.prototype.company = "Electronic Arts";
var revlin = new Employee("Revlin", "John");
revlin.company = "N/A"; // change revlin's employer
console.log( revlin.firstName +"\n"+ revlin.lastName +"\n"+ revlin.company );
console.log( steve.firstName +"\n"+ steve.lastName +"\n"+ steve.company );
console.log( andrew.firstName +"\n"+ andrew.lastName +"\n"+ andrew.company );
yielding:
Revlin
John
N/A
Steve
Kwan
Electronic Arts
Andrew
Wilson
Electronic Arts
Additionally, a neat way to add some level of encapsulation to these variables would be to use ES5's property descriptor object, including getters and setters. Just wanted to point that out to you. Again, thank you for the short tutorial, which I'm currently using to wrap my brain around JavaScript "classes"