1

I have a part of plugin which uses private variables and exposes public method :

JSBIN 1

function  myWorld()
    {
      var myPrivate=1;
      this.do1=function (){alert(myPrivate);} ;
    }

var a=new  myWorld();

a.do1() //1
alert(a.myPrivate); //undefined (as it should be)

But I want to prevent doing this again : new myWorld();

The only option I know is with object literal :

JSBIN 2

var myWorld=
    {
      myPrivate:1,
      do1:function (){alert(this.myPrivate);} 
    }


alert(myWorld.myPrivate); //1 ( ouch....)
myWorld.do1() //1

Question

How can encapsulate private fields and still prevent uses from myWorld to be instanced >1 times ?

5 Answers 5

2

Closures are a great tool to define the scope:

  var myWorld= (function(){
    var myPrivate = 1;
    return {
      do1:function (){alert(myPrivate);} 
    }
  }());


   myWorld.do1();

You might want to check out the free Learning JavaScript Design Patterns book

Sign up to request clarification or add additional context in comments.

Comments

2

Try something along these lines:

(function(){
  var instanciated = false;
  window.myWorld = function() {
    if( instanciated) throw new Error("myWorld can only be instanciated once!");
    instanciated = true;
    var myPrivate = 1;
    this.do1 = function(){alert(myPrivate);};
  }
})();

Comments

1

You can hide the private variable inside an IIFE:

var myWorld = (function() { 
    var myPrivate = 1;
    return { ... };
}());

Comments

1
var a = new function myWorld()
{
  var myPrivate=1;
  this.do1=function (){alert(myPrivate);} ;
}

This makes myWorld available only inside the function. If you don't event want it accessable there, then remove the name.

Comments

1

You could use a singleton pattern to maintain one instance of the object. Something like:

(function (global) {
    var _inst;

    global.myWorld = function () {
        if (_inst) throw new Error("A myWorld instance already exists. Please use myWorld.getInstance()");
        _inst = this;
    };

    global.myWorld.prototype = {
        do1: function() {
            console.log("do1");
        }
    };

    global.myWorld.getInstance = function() {
        if (_inst) return _inst;
        return new myWorld();
    };
}(window));

var world = new myWorld();
var world2 = myWorld.getInstance();
console.log(world === world2); // true
var world3 = new myWorld(); // throws Error

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.