I was reading chapter 2 of Apres Javascript Pro techniques and in particular the section about Provate Methods.
The following code snippet is shown as an example:
// Listing 2-23. Example of a Private Method Only Usable by the Constructor Function
function Classroom(students, teacher) {
// A private method for displaying all the students in the class
function disp() {
alert(this.names.join(", ")); // i think here there is an error. Should be alert(this.students.join(", "));
}
// Store the class data as public object properties
this.students = students;
this.teacher = teacher;
disp();
}
Apart the error at line 4, when i create a new Classroom object,
var class = new Classroom(["Jhon", "Bob"], "Mr. Smith");
the following error is thrown:
Uncaught TypeError: Cannot call method 'join' of undefined.
Reading at douglas.crockford.com/private.html, I found this:
By convention, we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.
Indeed creating a that variable pointing to this, the previous code work as expected.
function Classroom(students, teacher) {
var that;
// A private method used for displaying al the students in the class
function disp() {
alert(that.students.join(", "));
}
// Store the class data as public object properties
[...]
that = this;
disp();
}
So my question is:
- It is always necessary to create a that variable?
If yes, this means that the example was definitively wrong.
It is only necessary to store the value of
thisinto another variablethatif you for some reason want to keep the value thatthishad when calling the outer method.The error you get (Uncaught TypeError: Cannot call method ‘join’ of undefined.) means that the property
nameswas not found on thethisobject and that the value is thereforeundefinedand consequently cannot have anamesproperty.The value of
thisin JavaScript is a little complicated to know. If you invoke a functionfas a method, that is if you writeo.f()thenthisis bound tooinside the functionf. If you callfas a function, that isf()thenthisis bound to the global (window) object (!).Therefore, if you change the last line
disp();tothis.disp();, thenthiswill be what you expect insidedisp.The code is indeed wrong…