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を指すthat変数を作成すると、前のコードは期待どおりに機能します。

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が見つからなかったため、値がプロパティを持つことができないことを意味します。thisundefinednames

JavaScript での の値thisを知るのは少し複雑です。関数fメソッドとして呼び出す場合、つまり、書き込みを行う場合o.f()は、関数内にthisバインドされます。関数として呼び出すと、グローバル (ウィンドウ) オブジェクト (!) にバインドされます。offf()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 に答える