15

How can I create a function that can't be called from outside?

var obj = {
    function1: function(){
        alert("function1");
    },
    function2: function(){
        alert("function2...");
        obj.function1();
    }
};
// so how to make this function unaccessible 
obj.function1();
// and you could only call this function
obj.function2();
2
  • 1
    you want static function or static method? do you want it to be static at all? (the example doesn't clarify) Commented Jul 10, 2010 at 11:34
  • 1
    what is the difference between a static method and function? :S (btw sorry for using both words) Commented Jul 10, 2010 at 12:10

8 Answers 8

27

You may want to consider using the Yahoo Module Pattern. This is a singleton pattern, and the methods are not really static, but it may be what you are looking for:

var obj = (function () {

   //"private" variables:
   var myPrivateVar = "I can be accessed only from within obj.";

   //"private" method:
   var myPrivateMethod = function () {
      console.log("I can be accessed only from within obj");
   };

   return {
      myPublicVar: "I'm accessible as obj.myPublicVar",

      myPublicMethod: function () {
         console.log("I'm accessible as obj.myPublicMethod");

         //Within obj, I can access "private" vars and methods:
         console.log(myPrivateVar);
         console.log(myPrivateMethod());
      }
   };
})();

You define your private members where myPrivateVar and myPrivateMethod are defined, and your public members where myPublicVar and myPublicMethod are defined.

You can simply access the public methods and properties as follows:

obj.myPublicMethod();    // Works
obj.myPublicVar;         // Works
obj.myPrivateMethod();   // Doesn't work - private
obj.myPrivateVar;        // Doesn't work - private
Sign up to request clarification or add additional context in comments.

4 Comments

myPrivateMethod is not a "static" function. You missed the title.
I don't believe YAHOO has any rights on the module pattern ;)
@Crescent: I don't either, but that's how everyone seems to be calling it... Maybe I should have said "the Module Pattern, aka the Yahoo Module Pattern or the YUI Module Pattern" :)
I believe the pattern originated with Yahoo!'s Douglas Crockford, and was popularised through an article by Eric Miraglia from the YUI team: yuiblog.com/blog/2007/06/12/module-pattern
8

The simple answer is that you can't do both. You can create "private" methods or "static" methods, but you can't create Private static functions as in other languages.

The way you can emulate privacy is closure:

function f() {

  function inner(){}

  return {
    publicFn:  function() {},
    publicFn2: function() {}
  }
}

Here because of closure, the inner function will be created every time you call f, and the public functions can acces this inner function, but for the outside world inner will be hidden.

The way you create static methods of an object is simple:

function f() {}

f.staticVar = 5;
f.staticFn = function() {};
// or
f.prototype.staticFn = function() {};

Here the function object f will only have one staticFn which has access to static variables, but nothing from the instances.

Please note that the prototype version will be inherited while the first one won't.

So you either make a private method that is not accessing anything from the instances, or you make a static method which you doesn't try to access from the outside. ​

1 Comment

I guess the question is does javascript have static methods at all. f.prototype.staticFn is really just a public instance member of the prototype object. It is only static because, as a member of a different object instance, it doesn't have access to private members of this instance. You could do that with a private method too--just give the prototype instance a private method--it's just that this is not helpful because the child instance can't access the method. So shorter answer is there are no static methods in javascript.
4

You can use a closure, something along the lines of....

var construct = function() {

   var obj = {};

   var method1 = function() {
      alert("method1");
   }

   obj.method2 = function() {
         alert("method2...");
         method1();
   }

   return obj;
}

obj = construct();

Then:

obj.method2 is accessible, but obj.method1 doesn't exist for public usage. It can be only accessed using member functions of the class.

Comments

3

Use class. Though some of the features are still not shipped as it’s at Stage 3.

const instance = new (class Alpha {
	static #private_static_method() {
		console.info("I am private and static.");
	}
	static public_static_method() {
		Alpha.#private_static_method();
		console.info("I am public and static.");
	}
	#private_nonstatic_method() {
		console.info("I am private and non-static.");
	}
	public_nonstatic_method() {
		this.#private_nonstatic_method();
		console.info("I am public and non-static.");
	}
});

instance.constructor.public_static_method();
// instance.constructor.#private_static_method(); // impossible
instance.public_nonstatic_method();
// instance.#private_nonstatic_method(); // impossible

1 Comment

Seems like this shipped in all browsers? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
1

Objects can be produced by constructors, which are functions which initialize objects. Constructors provide the features that classes provide in other languages, including static variables and methods.

Read all about it at http://www.crockford.com/javascript/private.html

Comments

1

You can do it like this:

var obj = new function() {
  var method1 = function() { // private }
  this.method2 = function() { // public } 
}

obj.method1(); // not possible
obj.method2(); // possible

Note that I also use an anonymous constructor. This is sort of analogous to the Singleton pattern.

Comments

1

Maybe you want a proxy object containing only the public methods, e.g.

var obj = (function() {
  var obj = {
    method1: function(){
      alert("method1");
    },
    method2: function(){
      alert("method2...");
      obj.method1();
    }
  }
  return {
    method2: function() { return obj.method2.apply(obj, arguments) }
  }
})()

// you could only call this function
obj.method2();
// this function inaccessible 
obj.method1();

I don't see the point of private methods in javascript. If you don't want people calling a method then don't advertise it. Private methods also make debugging just that bit harder too.

Comments

1

This is how it really should be done.

var MyClass = new(function() {
    var privateStaticVariable = '';

    function privateStaticMethod() {

    }

    function construct() {
        var self = this;
        this.publicMethod = function() {};

        function privateMethod() {
            //maybe lest use our private static method
            privateStaticMethod();
        }
    }
    construct.publicStaticVariable = '';
    construct.publicStaticMethod = function() {};
    return construct;
})();

Now lets use it:

    var myClass = new MyClass();.....
MyClass.publicStaticMethod();
MyClass.publicStaticVariable = 'sfdsdf';
myClass.publicMethod();

.....

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.