2011-08-15 89 views
1

我在閱讀Apres Javascript Pro技術的第2章,特別是關於Provate方法的章節Javascript私有方法

下面的代碼段被示出爲一個示例:

// 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行中,當創建新的課堂對象,

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

以下錯誤被拋出:

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

閱讀douglas.crockford.com/private.html,我發現這個:

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.

確實創造了變量指向這個,前面的代碼按預期方式工作。

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

如果這些錯誤在第2章中,我不敢在後面的章節中看到代碼示例! – Matt

回答

3

如果您由於某種原因想要保留調用外部方法時的值this,則只需要將this的值存儲到另一個變量that中。

你得到的錯誤(遺漏的類型錯誤:無法調用未定義的「加入」),意味着該屬性namesthis對象上,並且因此該值undefined,因此不能有names屬性沒有被發現。

JavaScript中的this的值有點複雜。如果你調用一個函數f方法,那就是如果你寫o.f()然後this勢必o功能f內。如果您撥打f作爲函數,即f(),則this綁定到全局(窗口)對象(!)。

因此,如果您更改最後一行disp();this.disp();,然後this將是你期待內部disp什麼。

的代碼確實是錯誤的...

+0

我不認爲這會起作用。在示例代碼中,disp不是「課堂」的成員,因此this.disp()將引發錯誤 – tinyd

+0

這是正確的。 Disp也必須是課堂的成員。該代碼在很多方面都是錯誤的:...-) –

2

這是指一個函數(窗口對象,HTML元素...)的所有者,因此在私有函數中,您將無法訪問正在處理的對象。所以您將對象存儲在that變量中,以便您可以從該類中的任何私有方法訪問該對象。

1

你的第一個例子有,你沒有這個定義的另一個錯誤。名稱,但你的問題的答案基本上是'是' - 在disp函數體內,'this'變量被分配給全局範圍,所以你需要創建'that'變量。