Javascript Private Methods
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 this
into another variable that
if you for some reason want to keep the value that this
had when calling the outer method.
The error you get (Uncaught TypeError: Cannot call method 'join' of undefined.) means that the property names
was not found on the this
object and that the value is therefore undefined
and consequently cannot have a names
property.
The value of this
in JavaScript is a little complicated to know. If you invoke a function f
as a method, that is if you write o.f()
then this
is bound to o
inside the function f
. If you call f
as a function, that is f()
then this
is bound to the global (window) object (!).
Therefore, if you change the last line disp();
to this.disp();
, then this
will be what you expect inside disp
.
The code is indeed wrong...
this refers to the owner of a function (window object, HTML element...) so in a private function you won't be able to access the object you're working on. so you store the object in that
variable, so you can access it from any private method in the class.
Your first example has another error in that you're not defining this.names, but the answer to your question is basically 'yes' - inside the disp function body the 'this' variable is assigned to the global scope, so you need to create the 'that' variable.
精彩评论