最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How do I 'hide' variables in Javascript whilst exposing public static methods? - Stack Overflow

programmeradmin0浏览0评论

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
 |  Show 1 more comment

5 Answers 5

Reset to default 9

To 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

发布评论

评论列表(0)

  1. 暂无评论