I am currently rewriting some scientific C++ code using Javascript and I would like to keep the same basic organisation if at all possible. In the C++ code, there are a number of classes that contain a bunch of const
data in the from of many different arrays and a series of public static
methods that work on that data. I'm struggling with how to replicate something like this in Javascript.
At the moment I'm using something like the following:
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))
This works, but it exposes mars.x
etc. to the rest of the code which really doesn't need to know about it. If I use prototype
the methods will no longer be static and the code will be littered with new
calls, something I don't really want.
What I'm asking then, is: How do I hide variables in JavaScript whilst exposing static methods to the rest of the code? Or am I worrying about something I shouldn't be?
I am currently rewriting some scientific C++ code using Javascript and I would like to keep the same basic organisation if at all possible. In the C++ code, there are a number of classes that contain a bunch of const
data in the from of many different arrays and a series of public static
methods that work on that data. I'm struggling with how to replicate something like this in Javascript.
At the moment I'm using something like the following:
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))
This works, but it exposes mars.x
etc. to the rest of the code which really doesn't need to know about it. If I use prototype
the methods will no longer be static and the code will be littered with new
calls, something I don't really want.
What I'm asking then, is: How do I hide variables in JavaScript whilst exposing static methods to the rest of the code? Or am I worrying about something I shouldn't be?
Share Improve this question asked Jan 31, 2015 at 15:25 Scott MarleyScott Marley 4791 gold badge5 silver badges8 bronze badges 6- By the rest of the code, do you mean your classe's methods? – Wottensprels Commented Jan 31, 2015 at 15:26
- You're worrying about something you shouldn't be ! – adeneo Commented Jan 31, 2015 at 15:26
- @Sprottenwels No, I mean the other 50 or so classes-worth of functions (hundreds of functions in total). It feels as though I'm littering global with a lot of stuff that most of the other classes need to know nothing about. – Scott Marley Commented Jan 31, 2015 at 15:31
- Then @Azeirah's answer is what you should go for – Wottensprels Commented Jan 31, 2015 at 15:33
- Is this Node.js or client-side? – Ben Aston Commented Jan 31, 2015 at 15:39
5 Answers
Reset to default 9To hide a variable, you can use a closure (function scope)
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
I see that you want to give some structure and organize your javascript code. This is best handled in Javascript with what is popularly known as the Module Pattern
In a nutshell, it works like this:
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
This snippet and further reading is documented in Ben Cherry's article and Eric Miraglia's article. There are some neat variations of the module pattern, one such is the revealing module pattern by Christian Heilmann
Just make it local variable and use a getter function to get those. Also, try to maintain the naming-scheme. For constructors, it is that the name should start with a capital letter.
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]
You are correct to worry about this. Your code will become unmanageable if you do not solve this problem.
You use functions to control scope in JavaScript. JS doesn't have classes. ES6 (not in widespread use) has "classes", but only really in name.
You could try something like this:
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
I think the example below can give you a insight about private, public and static variables and methods.
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
To understand OOPS in JavaScript, I would recommend this tutorial: http://phrogz.net/JS/classes/OOPinJS.html