Come possiamo proteggere lo spazio dei nomi di un oggetto in Javascript?

6

Seguendo la mia precedente domanda: codice semplice Javascript per comprendere le basi OOP basate su prototipo Diciamo che eseguiamo in console questi due oggetti separati (anche se sono chiamati figlio e padre non c'è alcuna eredità tra loro):

var parent = {
    name: "parent",
    print: function(){
       console.log("Hello, "+this.name);
    }
};

var child = {
    name: "child",
    print: function(){
       console.log("Hi, "+this.name);
    }
};

parent.print()
// This will print: Hello, parent
child.print()
// This will print: Hi, child

temp =parent;
parent = child;
child = temp;


parent.print()
// This will now print: Hi, child
child.print() 
// This will now print: Hello, parent

Ora supponiamo che genitore sia una libreria, come un'applicazione HTML5 in un browser questo non può fare molto male perché è praticamente in esecuzione in modalità sandbox, ma ora con l'avvento di ChromeOS, FirefoxOS e altri sistemi operativi [Browser] saranno anche collegati ad un'API nativa, sarebbe una testa fuori dalla "sandbox". Ora, se qualcuno cambia lo spazio dei nomi, sarebbe più difficile per un revisore di codice (automatizzato o meno) individuare un uso errato se cambia lo spazio dei nomi.

La mia domanda sarebbe: ci sono molti modi in cui la situazione di cui sopra può essere fatto e cosa si può fare per proteggere questo spazio dei nomi? (Sia nella javascript stessa che con uno strumento di analisi del codice statico)

    
posta Eduard Florinescu 18.08.2012 - 14:21
fonte

1 risposta

11

C'è davvero molto poco che puoi fare (in tutti i browser) per proteggere le variabili globali.

Tuttavia una pratica comune (buona) è quella di incapsulare tutti i tuoi script in ( IIFE ) chiusure funzionali.

(function() {
    var parent = {
        name: "parent",
        print: function(){
           console.log("Hello, "+this.name);
        }
    };

    var child = {
        name: "child",
        print: function(){
           console.log("Hi, "+this.name);
        }
    };

    parent.print()
    // This will print: Hello, parent
    child.print()
    // This will print: Hi, child
})();

Questo significa che puoi usare parent e child all'interno dell'ambito di quella funzione. Mentre quello è limitante, è anche proteggere. Se ti servivano globalmente, un'opzione sarebbe mantenere un oggetto namespace:

var myGlobals = {};

(function( global ) {
    global.parent = {
        name: "parent",
        print: function(){
           console.log("Hello, "+this.name);
        }
    };

    global.child = {
        name: "child",
        print: function(){
           console.log("Hi, "+this.name);
        }
    };

    global.parent.print()
    // This will print: Hello, parent
    global.child.print()
    // This will print: Hi, child
})(myGlobals);

O se davvero ti servissero come singoli globali, potresti semplicemente fare:

(function() {
    window.parent = {
        name: "parent",
        print: function(){
           console.log("Hello, "+this.name);
        }
    };

    window.child = {
        name: "child",
        print: function(){
           console.log("Hi, "+this.name);
        }
    };

    parent.print()
    // This will print: Hello, parent
    child.print()
    // This will print: Hi, child
})();

Ma questo ti riporta al punto di partenza. In questo caso dovresti assicurarti di fare qualcosa per proteggere quelle variabili al momento del rimescolamento. Invece di scrivere:

temp =parent;
parent = child;
child = temp;

Puoi scrivere:

(function( parent, child ) {

    // Do some stuff.

    // Note: parent and child are references,
    // although they are switched, something like:
    //    child.hello = "hello";
    // will still edit the 'parent' object in the outer scope

})(child, parent); // Pass them in swapped.

Freeze e Seal (due nuovi metodi JS Object ) sono degni di nota in questa discussione nonostante non risolvono esattamente il tuo problema né avendo ancora il supporto per più browser.

    
risposta data 18.08.2012 - 18:29
fonte

Leggi altre domande sui tag