2015-01-31 5 views
5

Attualmente sto riscrivendo un codice C++ scientifico usando Javascript e vorrei mantenere la stessa organizzazione di base se possibile. Nel codice C++, ci sono un certo numero di classi che contengono un mucchio di dati const nel da molti matrici differenti e una serie di metodi public static che funzionano su quei dati. Sto cercando di replicare qualcosa di simile in Javascript.Come faccio a "nascondere" le variabili in Javascript mentre espongo i metodi statici pubblici?

Al momento sto usando qualcosa come il seguente:

function mars(){} 

mars.x = [{A:1, B:2, C:3},{A:1, B:2, C:3}]; //... 
mars.y = [{A:1, B:4, C:2},{A:1, B:2, C:3}]; //... 
// ...about 600 lines in total 

mars.doSomething = function(foo){ 
    var result = 0; 
    // Do lots of processing of above arrays 
    return result; 
} 

mars.doSomethingElse = function(bar){ 
    var result = 0; 
    // Do lots of processing of above arrays 
    return result; 
} 

console.log(mars.doSomething(3)) 

Questo funziona, ma espone mars.x ecc per il resto del codice che in realtà non ha bisogno di sapere su di esso. Se utilizzo prototype, i metodi non saranno più statici e il codice sarà pieno di chiamate new, qualcosa che non desidero.

Quello che sto chiedendo allora è: Come posso nascondere le variabili in JavaScript mentre esponi i metodi statici al resto del codice? O mi sto preoccupando di qualcosa che non dovrei essere?

+0

Per il resto del codice, intendi i metodi della tua classe? – Sprottenwels

+0

Ti stai preoccupando di qualcosa che non dovresti essere! – adeneo

+0

@Sprottenwels No, intendo le altre circa 50 classi di funzioni (centinaia di funzioni in totale). Mi sento come se fossi una figliata globale con un sacco di cose di cui la maggior parte delle altre classi non ha bisogno di sapere nulla. –

risposta

6

Per nascondere una variabile, è possibile utilizzare una chiusura (funzione di portata)

function mars() { 
    var staticFunctions = Object.create(null); // the same as {} 
    var x = [{A:1, B:2, C:3},{A:1, B:2, C:3}]; 
    var y = [{A:1, B:4, C:2},{A:1, B:2, C:3}]; 

    staticFunctions.doSomething = function (foo) { 
    return x; 
    }; 

    staticFunctions.doSomethingElse = function (bar) { 
    return y; 
    }; 

    return staticFunctions; 
} 

// you do need to instantiate mars however 
var m = mars(); 
// if you don't want that you can do 
var mars = (function() { 
    // same as above 
}()); // this invokes the function for you 
1

Basta renderlo variabile locale e utilizzare una funzione getter per ottenere quelli. Inoltre, prova a mantenere lo schema di denominazione. Per i costruttori, è che il nome dovrebbe iniziare con una lettera maiuscola.

function Mars(){ 
    var x = [{A:1, B:2, C:3},{A:1, B:2, C:3}]; 
    this.getArr = function(){ 
     return x; 
    } 
} 
var mars = new Mars(); 
mars.x; // undefined 
mars.getArr(); // [Object, Object] 
1

Lei ha ragione di preoccuparsi di questo. Il tuo codice diventerà ingestibile se non risolvi questo problema.

Si utilizzano le funzioni per controllare l'ambito in JavaScript. JS non ha classi. ES6 (non in uso diffuso) ha "classi", ma solo realmente nel nome.

si potrebbe provare qualcosa di simile:

var myApp = {}; 

(function(namespace){ 

    var X = [{A:1, B:2, C:3},{A:1, B:2, C:3}]; // Capitalized because 'constant'. 
    var Y = [{A:1, B:4, C:2},{A:1, B:2, C:3}]; // Capitalized because 'constant'. 

    function Mars() {} // Capitalized because this is a constructor function. 

    Mars.prototype.doSomething = function(foo) { 
    //do something with X 
    return X[foo]; // For example. 
    } 

    namespace.mars = new Mars(); // Lowercase on 'namespace.mars' because it is an instance. 

}(myApp)) 


// Use... 
myApp.mars.doSomething(foo); // Does something. 
Mars; // undefined 
X; // undefined 
Y; //undefined 
1

Credo che l'esempio che segue può dare una visione sulle variabili e metodi privati, pubblici e statici.

function Mars(){ 
    // private variables 
    var x = [{A:1, B:2, C:3},{A:1, B:2, C:3}]; 
    var y = [{A:1, B:4, C:2},{A:1, B:2, C:3}]; 

    // public variables 
    this.z = 2; 

    // privileged methods, can access private variables 
    this.getX = function(){ 
     return x; 
    }; 

    this.getY = function(){ 
     return y; 
    }; 
} 

// public prototype method, can not access private variables 
// access private variables through getters 
Mars.prototype.getZ = function(){ 
    return this.z; 
} 

// static variable 
Mars.staticVar = 1; 

// static method 
Mars.staticMethod = function(){ 
    console.log('It is the static method'); 
} 



var marsObj = new Mars(); 
console.log(marsObj.getX()); //Array [ Object, Object ] 
console.log(marsObj.getZ()); //2 

Mars.staticMethod(); // "It is the static method" 
marsObj.staticMethod(); // Exception: mars.staticMethod is not a function 

Per capire OOPS in JavaScript, consiglio questo tutorial: http://phrogz.net/JS/classes/OOPinJS.html

2

vedo che si vuole dare una certa struttura e organizzare il codice javascript. Questo è meglio gestito in JavaScript con quello che è popolarmente conosciuta come la Module Pattern

In poche parole, funziona così:

var MODULE = (function() { 
    var my = {}, 
     privateVariable = 1; 


    function privateMethod() { 
     // ... 
    } 

    my.moduleProperty = 1; 
    my.moduleMethod = function() { 
     // ... 
    }; 

    return my; 
}()); 

Questo frammento ed ulteriore lettura è documentato in Ben Cherry's article e Eric Miraglia's articolo. Ci sono alcune variazioni del modello del modulo, uno di questi è il modello del modulo rivelatore di Christian Heilmann