Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static variables with John Resig's simple class pattern?

I'm referring to this article.

In it, he defines a function that looks something like this:

function makeClass() {
    return function _class() {
        if(this instanceof _class) {
            if(typeof this.init === 'function') {
                this.init.apply(this, arguments);
            }
        } else {
            throw new Error('Constructor called as a function');
        }
    };
}

And then you can use it with something like this:

var MyClass = makeClass();

MyClass.prototype = {
    init: function(width, height) { ... },
    clear: function(ctx) {... },
    draw: function(ctx) { ... }
}

But now I want to initialize some static variables that should be shared across all instances. How do I do that?

like image 423
mpen Avatar asked Jun 23 '12 20:06

mpen


2 Answers

Well, the easiest approach is to define a static variable as a prototype property:

MyClass.prototype.xxx: 3, // ...
var t1 = new MyClass();
console.log(t1.xxx); // 3

... but it won't behave as static properties in other languages usually do:

var t2 = new MyClass();
t2.xxx = 5;
console.log(t1.xxx); // still 3 :(

The other way around is to use the fact that properties might be attached to functions as well:

MyClass.xxx = 3;

... but that narrows the ways we can use this property (it can't be called by t1.xxx from the previous examples).

There's another way, though. One can define static properties as variables, local to init method, accessible by methods, defined... in this init method as well. ) Like this.

   init: function() {
      var xxx = 3;
      MyClass.prototype.getXXX = function() {
         return xxx;
      };
      MyClass.prototype.setXXX = function(newXXX) {
         xxx = newXXX;
      }
   }

Then all one can use this property simply by this:

  var t1 = new MyClass();
  var t2 = new MyClass();
  console.log(t1.getXXX()); // 3
  console.log(t2.getXXX()); // 3
  t1.setXXX(5);
  console.log(t1.getXXX()); // 5 now
  console.log(t2.getXXX()); // 5 as well, behold the power of closures!

And here's a fiddle used.

UPDATE: this approach is better be used, I suppose, when we need to work with a (sort of) container of the static class data, that is to be shared by all objects - but we don't know exactly what can actually be stored in this container. Then we use just two functions - getStatic and setStatic - to store and retrieve data by string keys or some other identifiers. It may seem a bit confusing, and it is, but I think it may be worth an effort. )

like image 51
raina77ow Avatar answered Oct 12 '22 23:10

raina77ow


Just add it to MyClass itself.

MyClass.myVariable = 42;

It's not really static in the Java/C# sense, but gives you the same effect.

like image 29
Jordão Avatar answered Oct 13 '22 00:10

Jordão