Cosa significa che lo spazio dei nomi globale sarebbe inquinato?
Non capisco davvero cosa significhi inquinamento dello spazio dei nomi globale.
Risposte:
Nota rapida sulla raccolta dei rifiuti
Poiché le variabili perdono l'ambito, saranno idonee per la garbage collection. Se hanno ambito globale, non saranno idonei per la raccolta fino a quando lo spazio dei nomi globale non perde l'ambito.
Ecco un esempio:
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
Aggiungendolo al tuo spazio dei nomi globale (almeno per me) dovresti aggiungere 10.000 kb di utilizzo della memoria (win7 firefox) che non verranno raccolti. Altri browser potrebbero gestirlo in modo diverso.
Considerando che avere lo stesso codice in uno scope che esula dall'ambito in questo modo:
(function(){
var arra = [];
for (var i = 0; i < 2003000; i++) {
arra.push(i * i + i);
}
})();
Consentirà arradi perdere l'ambito dopo l'esecuzione della chiusura e sarà idoneo per la garbage collection.
Lo spazio dei nomi globale è tuo amico
Nonostante le molte affermazioni contro l'utilizzo dello spazio dei nomi globale, è tuo amico. E come un buon amico, non dovresti abusare della tua relazione.
Sii gentile
Non abusare (di solito indicato come "inquinante") lo spazio dei nomi globale. E quello che intendo per non abusare dello spazio dei nomi globale è: non creare più variabili globali. Ecco un cattivo esempio di utilizzo dello spazio dei nomi globale.
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);
Questo creerà 11 variabili globali che potrebbero essere sovrascritte o interpretate male da qualche parte.
Sii pieno di risorse
Un approccio più intraprendente, che non inquina lo spazio dei nomi globale, sarebbe racchiudere tutto questo nel modello del modulo e utilizzare solo una variabile globale mentre espone più variabili.
Ecco un esempio: (Si prega di notare che questo è semplice e non c'è gestione degli errori)
//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()al di fuori dello scopo? Sarebbe molto perfetto sottovalutare un altro concetto vicino a questa problematica!
In JavaScript, le dichiarazioni al di fuori di una funzione sono nell'ambito globale. Considera questo piccolo esempio:
var x = 10;
function example() {
console.log(x);
}
example(); //Will print 10
Nell'esempio sopra, xè dichiarato nell'ambito globale. Qualsiasi ambito figlio, come quello creato dalla examplefunzione, eredita effettivamente le cose dichiarate in tutti gli ambiti padre (in questo caso, è solo l'ambito globale).
Qualsiasi ambito figlio che dichiara nuovamente una variabile dichiarata nell'ambito globale oscurerà la variabile globale, causando potenzialmente bug indesiderati e difficili da tracciare:
var x = 10;
function example() {
var x = 20;
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10
Le variabili globali di solito non sono consigliate a causa della possibilità di causare problemi come questo. Se non avessimo usato l' varistruzione all'interno della examplefunzione, avremmo accidentalmente sovrascritto il valore di xnell'ambito globale:
var x = 10;
function example() {
x = 20; //Oops, no var statement
console.log(x); //Prints 20
}
example();
console.log(x); //Prints 20... oh dear
Se vuoi leggere di più e capirlo correttamente, ti suggerisco di passare attraverso la specifica ECMAScript . Potrebbe non essere la più eccitante delle letture, ma non aiuterà a finire.
Quando dichiari variabili globali, funzioni, ecc., Esse, ehm, vanno nello spazio dei nomi globale. A parte i problemi di prestazioni / memoria (che possono sorgere), è probabile che ti imbatti in uno sfortunato conflitto di nomi, quando ridefinirai una variabile importante o non utilizzerai il valore che pensi di utilizzare.
La definizione di cose nello spazio dei nomi globale deve essere evitata.