0

JavaScript では、次のようなクラスをシミュレートします。

function MyClass() {} // Constructor

MyClass.prototype.myField = "foo";

with次のキーワードを使用して、コードを読みやすくし、キーストロークを節約できると考えました。

function MyClass() {} // Constructor

with (MyClass.prototype)
{
    myField = "foo";

    myOtherField = "bar";

    myMethod = // etc
}

しかし、インスタンスを作成してこれらのフィールドのいずれかにアクセスしようとすると、undefined. ただし、with (MyClass.prototype)値を読み取ってから値を読み取ろうとすると、それは機能します。値を変更したり、新しいフィールドを作成しようとした場合にのみ失敗します。with (myObject)これは、元のインスタンスへの実際の参照ではなく、myObject のクローンにスコープを設定しているためだと思います。

それで、これを回避する方法はありますか?out の有無にかかわらず、必要な結果を生成する方法はありwithますか? MyClass.prototypeそれとも、何度も何度も書き出す運命にあるのでしょうか?

4

2 に答える 2

1

"次にインスタンスを作成し、それらのフィールドのいずれかにアクセスしようとすると、undefined"

そのように新しいフィールドを作成することはできません。

「そうしてwith (MyClass.prototype)から値を読み取ろうとすると、うまくいきます」

これは、既存のフィールドを読み取って更新できるためです。

「これは、元のインスタンスへの実際の参照ではなく、with (myObject)のクローンにスコープを設定しているためだと思います。」myObject

いいえ、それはオブジェクトへの実際の参照です。


この種の混乱は、人々が を避ける理由の一部ですwith


では、これを回避する方法はありますか?必要な結果を生成する方法はありますか?それとも、MyClass.prototype を何度も書き出す運命にありますか?」

変数を使用するだけです。

var p = MyClass.prototype;

p.myField = "foo";
p.myOtherField = "bar";
p.myMethod = "etc";

また、既存のプロトタイプ オブジェクトを上書きして、オブジェクト リテラル表記を許可することもできます...

function MyClass() {}

MyClass.prototype = {
    myField: "foo",
    myOtherField: "bar",
    myMethod: "etc"
};

必要に応じて を追加することもできconstructor: MyClassます。

于 2012-07-16T14:10:02.500 に答える
1

with ステートメントを使用すべきではない理由を説明しているこの記事を参照してください。myField、myOtherField、および myMethod 変数は、プロトタイプ オブジェクトのプロパティとしてまだ存在していないため、コード内でグローバル変数として作成されます。

于 2012-07-16T14:13:43.957 に答える