3

これは、Javascript の学習とアプリケーションの作成を同時に行う旅の中で出会ったものです。

var A = function (parent) {
    this.parent = parent;
},
    b = new Object();

b.a = new A(b);

この非常に単純なコードは、かなり興味深いものを生成します。

console.log(b.a.parent.a.parent.a);

http://i.imgur.com/g6fw6mZ.png これにより問題が発生しますか? 私のアプリケーションで同様のものを使用することを計画しているためです。

これを使用する理由は、親に属する変数を参照する必要があるためです。

こちらとほぼ同じ問題です。ただし、ここではクロージャーを使用できません。最も外側の関数すら持っていないからです。

私のコードの簡素化されたバージョンは次のとおりです。

var Scratchpad = function (canvas) {
    var ctx = canvas.getContext('2d');
    ctx.childMustAccessThis = 3;

    ctx.Brush = new Brush(ctx);
    return ctx;
},
    Brush = function (parent) {
        this.parent = parent;

        // Other vars
    };

Brush.prototype.getContext = function () {
    return this.parent.childMustAccesThis;
}

それぞれのブラシを使用して、これらのスクラッチパッド (変更されたコンテキスト オブジェクト) を複数作成する必要があります。

無害に思えますが、悪い習慣だと感じました。

リンクされたSO投稿で説明されている閉鎖など、他のことをいくつか試しました。しかし、もちろん、私のスクラッチパッド関数はそれ自体を返さず、代わりに変更された ctx オブジェクトを返すため、それは機能しませんでした。そのため、クロージャ変数はすべてガベージ コレクションされます (そうですか? 少なくともなくなっています)。

私の残りの試行は、Javascript オブジェクトの動作に関する誤った理解に依存していたため、言及する価値はありません。

それで、私はこれで何をすべきですか?今のままでいいの?または、これを処理するためのより良い方法について何か提案はありますか?

4

3 に答える 3

3

いわゆる循環参照です。

最新のガベージ コレクタ (Netscape 2.0 とは対照的に) は、これを完全に問題なく処理します。

古いバージョンの IE は、DOM オブジェクトと純粋な JS オブジェクトの間の循環参照を処理できないことに注意してください。

于 2013-09-24T17:25:10.767 に答える
1

最新のブラウザーでは、循環参照に問題はありません。

ただし、再帰アルゴリズムを実装するときに、それらを認識するか、少なくともそれらを検出するためのメカニズムを用意する必要があります。また、デフォルトでJSON.stringifyは循環参照について文句を言いますが、これは簡単に対処できます。

于 2013-09-24T17:30:42.213 に答える
0

JSON に変換する必要がない限り、循環参照オブジェクトを使用しても問題はありません。

明らかに再帰的なオブジェクト構造は、文字列として簡単に表すことができず、次のようなエラーが表示されます。

TypeError: Converting circular structure to JSON
于 2013-09-24T17:25:44.173 に答える