我正在阅读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();
}
所以我的问题是:
如果是,这意味着该示例明确错误。
答案 0 :(得分:3)
如果由于某种原因想要保留this
在调用外部方法时所拥有的值,则只需将that
的值存储到另一个变量this
中。
您得到的错误(未捕获的TypeError:无法调用未定义的方法'join'。)表示在names
对象上找不到属性this
,因此该值为{{1因此不能有undefined
属性。
JavaScript中names
的值有点复杂。如果您将函数this
作为方法调用,那么如果您编写f
,则o.f()
绑定到函数this
内o
1}}。如果您将f
称为函数,即f
,则f()
绑定到全局(窗口)对象(!)。
因此,如果您将最后一行this
更改为disp();
,那么this.disp();
将是您在this
内所期望的。
代码确实是错误的......
答案 1 :(得分:2)
这指的是函数的所有者(窗口对象,HTML元素......),因此在私有函数中,您将无法访问正在处理的对象。所以你将对象存储在that
变量中,这样你就可以从类中的任何私有方法访问它。
答案 2 :(得分:1)
你的第一个例子有另一个错误,你没有定义this.names,但你问题的答案基本上是'是' - 在disp函数体内,'this'变量被赋值给全局范围,所以你需要创建'那'变量。