13

私はこのクラスを持っています:

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }
}

そしてそれを呼びます:

    var myobj = new ctest();
    myobj.func1();

2番目のアラートが「huhu」をポップアップすることは想定されていませんか?func2はプライベートですが、var1パブリック変数にアクセスできませんか?

プライベート関数がパブリック変数にアクセスできない場合、どうすればよいですか?

前もって感謝します!

4

5 に答える 5

17

への呼び出しのコンテキストを提供する必要がありますfunc2

this.func1 = function() {
    alert(this.var1);
    func2.call(this);
    alert(this.var1);
}

コンテキストがない場合、呼び出しはグローバル オブジェクト (つまり ) を使用します。2 つのアラートの間に作成されているwindow現在のコードを実行すると表示されるはずです。window.var1

于 2012-05-23T11:18:03.313 に答える
12

関数はインスタンスに関連付けられていないため、の呼び出しは、予期されたインスタンスを指さfunc2ずに呼び出しとして終了します。this

呼び出しを修正してコンテキストを含めることができます。

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2.call(this);
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }
}

または、必要なオブジェクト参照を使用して変数を保持することもできます。

function ctest() {
    var that = this;
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        that.var1 = "huhu";
    }
}
于 2012-05-23T11:25:21.963 に答える
2

別のオプションは、次を使用することFunction.bindです。

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }.bind(this);
}

これに対するブラウザのサポートは完全ではないことに注意してください。

于 2012-05-23T11:30:43.513 に答える
2

JS にはプライベートというものはありませんが、クロージャーを使用してスコープを操作できます。

たとえば、あなたの例ではvar1、パブリック プロパティとして公開する必要はないとしましょう。次のようにコードを簡単に書き直すことができます。

function ctest() {
    var var1 = "haha";

    this.func1 = function() {
        alert(var1);
        func2();
        alert(var1);
    }

    var func2 = function() {
        var1 = "huhu";
    }
}

func1とは同じスコープを共有しているためfunc2(同じ関数で定義されているため) ctest、同じ変数にアクセスできます。もちろん、その場合はvar1公開していないので、:myobj.var1になりますundefined

プロパティとして公開する場合は、コンストラクターで作成したオブジェクト インスタンスにバインドvar1する必要があります。 func2

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }.bind(this);
}

それ以外の場合func2は、別のコンテキスト オブジェクト ( this) になります。ブラウザーがサポートしておらずbind、シムを使用したくない場合 (上記のリンクを参照)、クロージャーを再び利用できます。

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var context = this;
    var func2 = function() {
        context.var1 = "huhu";
    }
}

IMVHO はエレガントではありません。

于 2012-05-23T11:33:46.613 に答える
0
function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2(this);
        alert(this.var1);
    }
    var func2 = function(obj) {
        obj.var1 = "huhu";
    }
}

そして、この問題を解決する他の方法があります。他の回答を確認してください:)

于 2012-05-23T11:19:01.020 に答える