1. ホーム
  2. javascript

[解決済み] グローバルネームスペースが汚染されるとはどういう意味ですか?

2022-12-12 22:37:50

質問

グローバル名前空間が汚染されるとはどういうことですか?

グローバル名前空間が汚染されるってどういうことなのかよくわからないんだけど。

どのように解決するのですか?

ガベージコレクションの簡単な説明

変数がスコープを失うと、それらはガベージコレクションの対象となります。もし変数がグローバルにスコープされている場合、グローバルな名前空間がスコープを失うまで、それらは収集の対象にはなりません。

以下はその例です。

var arra = [];
for (var i = 0; i < 2003000; i++) {
 arra.push(i * i + i);
}

グローバル名前空間にこれを追加すると、(少なくとも私の場合)10,000kbのメモリ使用量(win7 firefox)が追加されますが、これは収集されません。他のブラウザーは、これを異なる方法で処理するかもしれません。

一方、このようにスコープの外に出るスコープで同じコードを持っています。

(function(){
 var arra = [];
 for (var i = 0; i < 2003000; i++) {
  arra.push(i * i + i);
 }
})();

を許可する arra がクロージャの実行後にスコープを失い、ガベージコレクションの対象となることを許可します。

グローバル名前空間はあなたの味方です

グローバル名前空間の使用に対する多くの主張にもかかわらず、グローバル名前空間はあなたの友人です。そして、良い友人のように、あなたはその関係を乱用してはいけません。

優しくする

グローバル名前空間を乱用しない(通常、quot;polluting"と呼ばれる)。グローバル名前空間を乱用しないとは、複数のグローバル変数を作らないということです。ここでは 悪い グローバル名前空間の使用例です。

var x1 = 5;
var x2 = 20;
var y1 = 3
var y2 = 16;

var rise = y2 - y1;
var run = x2 - x1;

var slope = rise / run;

var risesquared = rise * rise;
var runsquared = run * run;

var distancesquared = risesquared + runsquared;

var distance = Math.sqrt(dinstancesquared);

これは11個のグローバル変数を作成することになり、どこかで上書きされたり、誤変換されたりする可能性があります。

臨機応変に対応する

グローバル名前空間を汚染しない、より機知に富んだアプローチは、これをすべてモジュールパターンで包み、複数の変数を公開しながら1つのグローバル変数のみを使用することです。

以下はその例です。(これは単純なもので、エラー処理はないことに注意してください)

//Calculate is the only exposed global variable
var Calculate = function () {
 //all defintions in this closure are local, and will not be exposed to the global namespace
 var Coordinates = [];//array for coordinates
 var Coordinate = function (xcoord, ycoord) {//definition for type Coordinate
   this.x = xcoord;//assign values similar to a constructor
   this.y = ycoord;
  };

  return {//these methods will be exposed through the Calculate object
   AddCoordinate: function (x, y) {
   Coordinates.push(new Coordinate(x, y));//Add a new coordinate
  },

  Slope: function () {//Calculates slope and returns the value
   var c1 = Coordinates[0];
   var c2 = Coordinates[1];
   return c2.y - c1.y / c2.x - c1.x;//calculates rise over run and returns result
  },

  Distance: function () {
   //even with an excessive amount of variables declared, these are all still local
   var c1 = Coordinates[0];
   var c2 = Coordinates[1];

   var rise = c2.y - c1.y;
   var run = c2.x - c1.x;

   var risesquared = rise * rise;
   var runsquared = run * run;

   var distancesquared = risesquared + runsquared;

   var distance = Math.sqrt(distancesquared);

   return distance;
  }
 };
};

//this is a "self executing closure" and is used because these variables will be
//scoped to the function, and will not be available globally nor will they collide
//with any variable names in the global namespace
(function () {
 var calc = Calculate();
 calc.AddCoordinate(5, 20);
 calc.AddCoordinate(3, 16);
 console.log(calc.Slope());
 console.log(calc.Distance());
})();