グローバル名前空間が汚染されるとはどういう意味ですか?
汚染されるグローバル名前空間の意味がよくわかりません。
回答:
ガベージコレクションに関するクイックノート
変数がスコープを失うと、ガベージコレクションの対象になります。それらがグローバルにスコープ指定されている場合、グローバル名前空間がスコープを失うまで、それらは収集に適格ではありません。
次に例を示します。
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
これをグローバル名前空間に追加すると(少なくとも私にとって)、10,000 kbのメモリ使用量(win7 firefox)が必要となり、収集されません。他のブラウザでは、これを異なる方法で処理する場合があります。
これと同じコードを、次のようにスコープ外に出るスコープに含めます。
(function(){
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
})();
できるようになりますarra閉鎖実行後にスコープを失い、ガベージコレクションの対象であることを。
グローバル名前空間はあなたの友達です
グローバル名前空間の使用に対する多くの主張にもかかわらず、それはあなたの友達です。そして、良い友達のように、あなたはあなたの関係を乱用すべきではありません。
穏やかな
グローバル名前空間を乱用しないでください(通常は「汚染」と呼ばれます)。そして、グローバル名前空間を乱用しないとは、複数のグローバル変数を作成しないことです。以下は、グローバル名前空間を使用した悪い例です。
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());
})();
Calculate.prototype.Slope()ですか?この問題に近い別の概念を理解することは非常に完璧です!
JavaScriptでは、関数外の宣言はグローバルスコープ内にあります。この小さな例を考えてみましょう:
var x = 10;
function example() {
console.log(x);
}
example(); //Will print 10
上記の例でxは、グローバルスコープで宣言されています。example関数によって作成されるような子スコープは、親スコープで宣言されたものを効果的に継承します(この場合、それは単なるグローバルスコープです)。
グローバルスコープで宣言された変数を再宣言する子スコープは、グローバル変数をシャドウし、潜在的に望ましくない、追跡が困難なバグを引き起こします。
var x = 10;
function example() {
var x = 20;
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10
このような問題を引き起こす可能性があるため、通常、グローバル変数は推奨されません。関数var内でステートメントを使用しなかった場合、example誤っxてグローバルスコープのの値を上書きしてしまうことになります。
var x = 10;
function example() {
x = 20; //Oops, no var statement
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 20... oh dear
詳細を読んで正しく理解したい場合は、ECMAScript仕様を確認することをお勧めします。読み取りの中で最もエキサイティングではないかもしれませんが、それは終わりのないものになるでしょう。
グローバル変数や関数などを宣言すると、それらは、ええと、グローバル名前空間に移動します。パフォーマンス/メモリの問題(発生する可能性があります)とは別に、重要な変数を再定義するか、使用していると思われる値を使用しない場合、不幸な名前の衝突が発生する可能性があります。
グローバル名前空間での定義は避けてください。