Javascript私有方法

时间:2011-08-15 13:12:43

标签: javascript private-methods

我正在阅读Apres Javascript Pro技术的第2章,特别是关于 Provate Methods 的部分。

以下代码段作为示例显示:

// 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();
}

除了第4行的错误,当我创建一个新的Classroom对象时,

var class = new Classroom(["Jhon", "Bob"], "Mr. Smith");

抛出以下错误:

Uncaught TypeError: Cannot call method 'join' of undefined.

在douglas.crockford.com/private.html上阅读,我发现了这个:

  

按照惯例,我们创建一个私有变量。这用于使对象可用于私有方法。这是ECMAScript语言规范中的错误的解决方法,导致对内部函数的设置不正确。

确实创建了一个指向 this 变量,之前的代码按预期工作。

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();             
}

所以我的问题是:

  • 始终需要创建一个变量吗?

如果是,这意味着该示例明确错误。

3 个答案:

答案 0 :(得分:3)

如果由于某种原因想要保留this在调用外部方法时所拥有的值,则只需将that的值存储到另一个变量this中。

您得到的错误(未捕获的TypeError:无法调用未定义的方法'join'。)表示在names对象上找不到属性this,因此该值为{{1因此不能有undefined属性。

JavaScript中names的值有点复杂。如果您将函数this作为方法调用,那么如果您编写f,则o.f()绑定到函数thiso 1}}。如果您将f称为函数,即f,则f()绑定到全局(窗口)对象(!)。

因此,如果您将最后一行this更改为disp();,那么this.disp();将是您在this内所期望的。

代码确实是错误的......

答案 1 :(得分:2)

这指的是函数的所有者(窗口对象,HTML元素......),因此在私有函数中,您将无法访问正在处理的对象。所以你将对象存储在that变量中,这样你就可以从类中的任何私有方法访问它。

答案 2 :(得分:1)

你的第一个例子有另一个错误,你没有定义this.names,但你问题的答案基本上是'是' - 在disp函数体内,'this'变量被赋值给全局范围,所以你需要创建'那'变量。