开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜