1

我正在阅读 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();             
}

所以我的问题是:

  • 总是需要创建一个那个变量?

如果是,这意味着该示例绝对是错误的。

4

3 回答 3

3

仅当您出于某种原因想要保留调用外部方法时的值时,才需要将 的值存储this到另一个变量中。thatthis

您得到的错误(Uncaught TypeError: Cannot call method 'join' of undefined.)意味着在对象names上找不到该属性this,因此该值是undefined并且因此不能具有names属性。

JavaScript 中的值this有点复杂。如果你调用一个函数f作为一个方法,也就是说如果你写o.f()thenthis就绑定到o函数内部f。如果您f作为函数调用,f()则将this绑定到全局(窗口)对象(!)。

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

代码确实错了……

于 2011-08-15T13:22:33.363 回答
2

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

于 2011-08-15T13:21:26.207 回答
1

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

于 2011-08-15T13:26:04.007 回答