2012-01-14 14 views

risposta

93

breve nota sulla Garbage Collection

come variabili perdono ambito, saranno per la garbage collection. Se hanno un ambito globale, non saranno idonei per la raccolta finché lo spazio dei nomi globale non perderà l'ambito.

Ecco un esempio:

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

L'aggiunta di questo al vostro namespace globale (almeno per me) dovrebbero pubblicitarie 10.000 kb di utilizzo della memoria (Win7 firefox) che non saranno raccolti. Altri browser possono gestirli diversamente.

considerando che, tenuto lo stesso codice in un ambito che va fuori portata come questo:

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

permetterà arra a perdere portata dopo la chiusura eseguito ed essere per la garbage collection.

namespace globale è tuo amico

Nonostante i molti crediti nei confronti utilizzando namespace globale, è tuo amico. E come un buon amico, non dovresti abusare della tua relazione.

essere gentile

Non abusare (solitamente indicato come "inquinante") lo spazio dei nomi globale. E ciò che intendo non abusare del namespace globale è - non creare più variabili globali. Ecco un esempio errato 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 errate da qualche parte.

essere intraprendenti

Un approccio più intraprendente, che non inquina namespace globale, sarebbe quello di avvolgere tutto questo nel modello del modulo e utilizzare solo una variabile globale, esponendo più variabili.

Ecco un esempio: (Si prega di notare che questo è semplice e non v'è alcuna 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()); 
})(); 
+7

mantenendo le variabili all'interno di una chiusura assicura che vengano raccolte informazioni inutili. – theJava

+1

Risposta molto interessante, puoi spiegarci qual è la differenza tra un ritorno e l'altro come hai fatto nel tuo scope, e usando per esempio 'Calculate.prototype.Slope()' al di fuori dell'ambito? Sarebbe molto perfetto per capire un altro concetto vicino a questa problematica! – Ludo

+0

Grazie per questa buona spiegazione. Domanda veloce: cosa ti piacerebbe vedere sulla gestione degli errori in quel frammento? – Sentenza

6

Quando si dichiarano variabili globali, funzioni, ecc., Esse, ehm, passano allo spazio dei nomi globale. A parte i problemi di prestazioni/memoria (che possono sorgere), è probabile che si verifichi uno sfortunato conflitto di nomi, quando ridefinisci una variabile importante o non usi il valore che pensi di usare.

Definire le cose nello spazio dei nomi globale deve essere evitato.

+1

Un modo per evitare di definire le cose nello spazio dei nomi globale consiste nell'utilizzare le variabili locali (dichiarate con "var" all'interno di una funzione), ma la variabile è ... locale per la funzione. Questo dovrebbe essere fatto il più possibile. –

14

In JavaScript, le dichiarazioni all'esterno di una funzione sono nell'ambito globale. Considerate questo piccolo esempio:

var x = 10; 
function example() { 
    console.log(x); 
} 
example(); //Will print 10 

Nell'esempio di cui sopra, x viene dichiarata in ambito globale. Qualsiasi ambito figlio, ad esempio quello creato dalla funzione example, eredita effettivamente le cose dichiarate in qualsiasi ambito padre (in questo caso, è solo l'ambito globale).

Ogni portata bambino che redeclares una variabile dichiarata nel campo di applicazione globale ombra la variabile globale, causando potenzialmente indesiderate, difficile da tenere traccia di bug:

var x = 10; 
function example() { 
    var x = 20; 
    console.log(x); //Prints 20 
} 
example(); 
console.log(x); //Prints 10 

variabili globali sono di solito non raccomandato a causa del potenziale di causare problemi come questo Se non abbiamo usato la dichiarazione var all'interno della funzione example, avremmo sovrascritti accidentalmente il valore della x nell'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 volete saperne di più e capire come si deve, io suggerisco di andare attraverso il ECMAScript specification. Potrebbe non essere la più emozionante delle letture, ma aiuterà a non finire.

Problemi correlati