0

.prototypeを使用して作成された関数は、ローカル変数にアクセスできるはずだと思いました。これが私が話していることです:

function obj() {
    var a = "String";

    this.innerPrint = function() {
        document.write("<p>" + a + "</p>");
    };
}

obj.prototype.outerPrint = function() {
    document.write("<p>" + a + "</p>");
};

var inst = new obj();
inst.innerPrint();
inst.outerPrint();

私が思うに、これらの機能は両方とも同じことをするだろうということです。しかし、実際に起こったことは、outerPrintが変数aにアクセスできないことです。プロトタイプ関数でローカルを取得する方法を誰かに説明してもらえますか。

このコードを実行しているフィドルは次のとおりです:http: //jsfiddle.net/Wryte/mxXzg/

ちなみに、オブジェクトの各インスタンス化には関数のコピーがありませんが、それぞれが同じものを指しているため、プロトタイプ関数を使用したいと思います。

4

4 に答える 4

1

コンストラクターの実行が終了した後も変数aにアクセスできるようにする場合は、コードを次のように変更します。

function obj() {
    this.a = "String";

    this.innerPrint = function() {
        document.write("<p>" + this.a + "</p>");
    };
}

obj.prototype.outerPrint = function() {
    document.write("<p>" + this.a + "</p>");
};

または、直接書き込みアクセスを提供したくない場合は、ゲッターを定義します。

function obj() {
    var a = "String";
    this.getA = function() {
        return a;
    }
    this.innerPrint = function() {
        document.write("<p>" + a + "</p>");
    };
}

obj.prototype.outerPrint = function() {
    document.write("<p>" + this.getA() + "</p>");
};
于 2012-09-26T13:20:05.130 に答える
1

'a'を宣言すると、obj()関数の字句スコープで宣言されます。すべてのインスタンス変数もプロトタイプ化する必要があるため、インスタンス化されたvar aものはとして宣言する必要がありますthis.a

于 2012-09-26T13:22:55.173 に答える
1

もちろんそうではありません。最初の関数の外部で定義された別の関数から、ある関数のローカルにアクセスすることはできません。2番目が最初のプロトタイププロパティで定義されているかどうかは関係ありません。関数を呼び出すたびに新しいローカル変数がobj定義されるため、それにアクセスする必要のある関数の個別のコピーが必要になることは避けられません。a

実際には、その変数がインスタンスプロパティではなくローカルである必要があると想定しているため、考えられるアプローチの1つは、関数の周りに薄いローカルラッパーのみを配置することです。

function obj() {
    var a = "String";

    this.wrapper = function() { outerPrint.call(this, a); }
    this.innerPrint = function() {
        document.write("<p>" + a + "</p>");
    };
}

function outerPrint(a) {
    document.write("<p>" + a + "</p>");
};

繰り返しになりますが、の代わりにもっと複雑な関数があると思います。outerPrintこのようにして、最小限のラッパーの複製を犠牲にして、大きな関数の複製を回避できます。このようにして、変数のプライバシーを保持しa、パブリックゲッターは外部コードがその値を検査できるようにします。

更新: @Bergiの発言で、コンストラクターが定義されouterPrintているのと同じスコープでローカル関数を作成するようにコードを変更しました。プロトタイプには含まれなくなったため、インスタンスobjを直接呼び出すことはできません。objグローバル関数を回避するために、すべてのコードが関数スコープ内にある必要があることに注意してくださいouterPrint

于 2012-09-26T13:25:51.743 に答える
0

いいえ、ローカル変数です。。という名前のプロパティがあるため、スコープルールはバイパスされませんprototype

変数には、コンストラクター内で定義された関数からのみアクセスできます。そのため、特権と呼ばれます。もちろん、それらがパブリックメソッドとしてアクセスできる場合は、外部から呼び出すことができます。

Obj.prototype.outerPrint = function() {
    this.innerPrint();
};
于 2012-09-26T13:27:23.190 に答える