2
var person = {
    name: 'John'
};

function Pet1(person) {
    var owner = person.name;
    this.showOwner = function() {
        alert(owner);
    }
}

function Pet2(person) {
    this.showOwner = function() {
        alert(person.name);
    }
}

var pets = [new Pet1(person), new Pet2(person)];

...

pets.splice(0, 1);
pets.splice(0, 1);

上記のどのコードが、JS GCがPet1とPet2のインスタンスがスコープ外になったとき、またはどちらへの参照がなくなったときにそれらのインスタンスを収集しないようにします。私が知っているのはPet2ですが、Pet1もJS GCを妨げると思いませんか?

4

2 に答える 2

1

あなたのコメントからの質問について:

人物(この場合はグローバル)変数は、Pet1とPet2のインスタンスがガベージコレクションされるのを防ぎます(スコープ外で参照がない場合)

いいえ、なぜそれが必要ですか?personPetインスタンスを参照していません。その逆です。配列からPetインスタンスへの参照を削除するとpets、GCがそれらを収集することを妨げるものは何もありません( " ..."コードがpets[0]またはへの他の参照を作成しないと仮定しますpets[1])。

于 2013-03-16T15:06:08.723 に答える
0

答えは「状況次第」です。

最新のエンジンに関してはperson、システム内の他の場所から削除された場合でも、議論で言及されていたとしても、クロージャー内にあるにもかかわらず、公に公開されている方法からは二度と参照されないため、収集できます。利用可能。

したがって、スコープの痕跡部分の削除をサポートするエンジンは、そのオブジェクトでGCを簡単に実行できます。

では、問題は、どのエンジンがそれを実行し、それらのエンジンのどのバージョンがそれを実行するかということです。
その答えはわかりません。

それは可能ですが、古いまたは古いJSエンジンのメモリに常駐し続けることができます。

編集

次のように考えてくださいvar pet1 = new Pet1(person); 。Pet1は人を使用してpet1の値を設定しました。
人はpet1について何も知りません。

var pet2 = new Pet2(person);
pet2には、人を探して値を読み取る機能があります。
したがって、コードで人が二度と言及されていなくても、pet2が人を見つける必要のある関数を呼び出す可能性があるため、削除することはできません...
人はまだpet2が何であるかを知りません。

pet2が不要になったとき、および上記の配列から削除されたとき、およびそれを参照したすべての変数/オブジェクトプロパティ/配列インデックスの参照が削除されたとき(スコープ内で作成された関数の削除を含む)他のコードがpet2を探していない/ぶら下がっていないため、に存在し、それを参照している場合は、どういうわけか削除できます。

pet2がなくなると、人は他の場所では使用されなくなります。
したがって、人を収集対象としてマークすることができます。

GCは、物にアクセスできるものがすべてです。
他のものがまだオブジェクトについて話している場合、オブジェクトを削除することは許可されていません。
インスタンスは50個の引数に依存し、120個の他の外部オブジェクトへの参照を持つことができますが、他の誰も気にしない場合でも、そのインスタンスは収集できます

于 2013-03-16T07:51:31.430 に答える