2012-03-19 11 views
7

Non sono un buon utente di JavaScript, ma posso fare le cose con esso. Non sono orgoglioso del codice che ho scritto in JavaScript, quindi ho deciso di cambiarlo. Ecco il mio primo passo:Il modo di scoping buona in JavaScript

Sto provando a creare la mia libreria per un progetto e il seguito è la struttura iniziale.

window.fooLib = {}; 

(function (foo) { 
    "use strict"; 

    foo.doSomeStuff = function(param1) { 

     console.log(new AccommProperty(param1)); 
    } 

    //some internal function 
    function AccommProperty(nameValue) { 
     var _self = this; 
     _self.name = nameValue; 
    } 

}(fooLib)); 

ho usato funzione immediatamente invocato espressione qui per inizializzare la mia variabile. In questo caso è fooLib.

Non sono sicuro se dovrei fare altre cose per rendere window.fooLib più sicuro. Voglio dire che può essere sostituito da qualsiasi altro codice che verrà eseguito dopo il mio codice se ho capito bene JavaScript.

Quali sono i tuoi pensieri?

+0

utilizzare "use strict"; e proteggerti, questo è tutto ciò che puoi fare. – Christoph

+0

@Christoph I ha usato '" usa strict; "' sopra come puoi vedere. È questo il modo e il luogo giusto per usarlo? – tugberk

+2

sì. [vedi l'articolo di john resig] (http://ejohn.org/blog/ecmascript-5-objects-and-properties/) su come la protezione può essere raggiunta o su 'Object.freeze (obj)' su https: // developer .mozilla.org/it/JavaScript/Riferimento/Global_Objects/Object/freeze – Christoph

risposta

1

Se si desidera impedire la sovrascrittura delle variabili, è possibile utilizzare Object.defineProperty() con scrivibile: falso, configurabile: falso. Nel tuo caso:

(function() { 
    "use strict"; 
    var foo = {}; 
    //some internal function 
    function AccommProperty(nameValue) { 
     var _self = this; 
     _self.name = nameValue; 
    } 
    foo.doSomeStuff = function(param1) { 

     console.log(new AccommProperty(param1)); 
    } 
    Object.defineProperty(window, "foolib", {value:foo}); 
}()); 

Ancora, non c'è una buona ragione per quello. Avrebbe bisogno di EcamScript 5.1 per funzionare e non ci sono shim in giro; forse qualcosa con getter/setter per evitare la sovrascrittura con l'operatore =.

Tuttavia, non è necessario rendere la libreria non sovrascrivibile. Basta non usare il codice sul tuo sito che sovrascrive la lib. O forse qualcuno vuole anche sovrascrivere le tue funzioni con un'altra, migliore libreria con la stessa interfaccia?

Se la domanda riguarda una libreria da condividere, con possibili conflitti di namespace con altri, è possibile dare un'occhiata a jQuery.noConflict.

0

Ogni oggetto JavaScript può essere sostituito. Questa è la natura di JavaScript ed è impossibile cambiarla. Quindi non puoi rendere sicuro il tuo codice in questo senso.

Per quanto riguarda le funzioni selimate: è necessario utilizzarle quando si desidera avere variabili locali ma sono visibili a tutte le funzioni. Quindi nel tuo caso AccommProperty è una variabile del genere. La definizione dell'ambito interno doSomeStuff non fa alcuna differenza a meno che lo doSomeStuff utilizzi le variabili definite all'interno dell'ambito.

Quindi, quando si desidera nascondere le variabili da utente e/o sono necessari i globali e si ha paura dei conflitti di nomi, utilizzare le funzioni selezionate.

+0

grazie! cambiato il mio codice di esempio. Ora ha più senso, penso. – tugberk

-1

Non sono sicuro di dover fare altre cose per rendere window.fooLib più sicuro. Voglio dire che può essere sostituito da qualsiasi altro codice che verrà eseguito dopo il mio codice se ho capito bene JavaScript.

Si potrebbe provare a fare window.fooLib una variabile locale invece. Utilizzando closures and nested functions uno può emulare uno spazio dei nomi in cui è possibile inserire tutti i dati, invece di metterla nel l'ambito globale o collegandolo a window oggetto:

(function() { 

    // all functions nested in foo() have access to fooLib. 
    fooLib = {} 

    fooLib.doSomeStuff = function(param1) { 
     console.log(param1); 
     console.log(fooLib); 
    } 

    //some internal function 
    function AccommProperty() { 
     console.log(fooLib); 
    } 

}()); 

Vedere Javascript Closures: Encapsulating Related Functionality per maggiori dettagli.

+0

ok ma in questo caso non posso usare 'fooLib' al di fuori di questo IIFE e non avrà molto senso se voglio creare una libreria. O mi sbaglio? – tugberk

+0

Anche il tuo fooLib è collegato alla finestra ... E hai bisogno di questo, per fornire un accesso esterno. (Questo è il senso di una libreria ?!) Qualsiasi oggetto in JS che crei (ES3) può essere sovrascritto se non lavori con ES5 e proteggerlo. – Christoph

+0

@tugberk: si mette l'intera libreria in una funzione che mantiene lo stato della libreria come variabili locali. Tutte le funzioni della libreria diventano funzioni annidate. –