Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is enforcing private methods in Javascript a good idea?

I was having a discussion with a fellow developer on whether hacking into javascript private functions makes sense or not.

Alternatives are:

  1. A constructor and a prototype with all the functions in, non-API methods(private) will be just named with an underscore _function_name so that devs know what can they call and what they cannot call.
  2. A constructor and a prototype for API functions, and free functions as private functions inside a private namespace that hides them from the rest of the namespaces except this one.

We do not consider other approaches, like creating private functions in the constructor of the form var private_var= function(){} because that would trigger the creation of all those functions each time an object gets instantiated and each object would have its own set.

Reasons we had for them:

1

  • Javascript does not support private functions per se, in fact, there is no concept of private/protected/public visibility, so this is basically a hack
  • Using the underscore in method names marks clearly what are the boundaries for the given class/prototype, there is no need for "enforcing" it, in fact languages like Python don't have private methods and python users never seemed to care about it apart from using underscores
  • Even if private gets enforced, what sense does it make in a language where you can just dynamically substitute public methods?
  • Affects readability, quite a lot, private functions are separated into another set of braces for their scope, they cannot use this or they need to be called with function.call(object) or function.apply(object)

2

  • Brings a clear limitation by encapsulating private methods far from the class/prototype user hands
  • It is more or less the industry standard, lots of javascript developers use it like that

We suspect that because lots of developers use it, there might be another reason, like performance or so, to be used like that.

As our knowledge of Javascript is quite limited, we decided to post this in stackoverflow to see what approach is better and why.

like image 975
Arkaitz Jimenez Avatar asked Oct 15 '12 20:10

Arkaitz Jimenez


People also ask

What is the drawback of creating true private methods in JavaScript?

There are two major disadvantages of creating the true private method in JavaScript. Cannot call private method outside the class. Create memory inefficiency when different objects are created for the same class, as a new copy of the method would be created for each instance.

Should I use private methods?

Private methods are useful for breaking tasks up into smaller parts, or for preventing duplication of code which is needed often by other methods in a class, but should not be called outside of that class.

Can you have private methods in JavaScript?

JavaScript allows you to define private methods for instance methods, static methods, and getter/setters. The following shows the syntax of defining a private instance method: class MyClass { #privateMethod() { //... } }

What is the point of private methods?

A private method is an access modifier used in a class that can only be called from inside the class where it is defined. It means that you cannot access or call the methods defined under private class from outside.


1 Answers

How would you hack into javascript private functions and for what purpose?

I think the different methods of creating classes, private functions, etc depend on your motivations.

The underscore convention helps when you try to unit test and you really want to break up what might look like a giant method from the outside.

I feel that in every other case you should try to make things truly private. If you are trying to expose a nice, clean API for others to work with they should not need to see what is behind the scenes. Why expose that? This leads to general convos about private and public: Why "private" methods in the object oriented?

You do have a few choices for privatizing methods and some of these choices impact performance.

Underscore convention:

function Pizza() {
   this._pepperoni = function () {};
}

or

function Pizza() {
}

Pizza.prototype._pepperoni = function () {};

Scoping

function Pizza() {
    function pepperoni() {};
}

Namespacing/Modules

var pizza = pizza || {};
(function() {
    function pepperoni() {};
    function create() {
        pepperoni();
    }
    window.pizza.create = create; // or module.export = pizza or both
}());

Module Pattern

(function(){
    function pepperoni() {};
    function Pizza() {
        pepperoni();
    }

    window.Pizza = Pizza;
}());

About recreating your functions vs defining them once. First if you would like to use internal private members and still use "this" just create a new variable called self and assign this to it:

function Pizza() {
    var self = this;
    function pep() {
       self.x = 1;
    }
}

Next, I attempted to test the performance difference between redefining and writing functions up front: http://jsperf.com/private-methods I think it saves you a little less than 20% on ops/sec to have your functions be recreated every time.

I am not recommending any approach, they are all valid and useful at various times. Sometimes it is more about semantics, sometimes it's about performance and other times it is to meet some end like unit testing.

like image 175
Parris Avatar answered Nov 10 '22 13:11

Parris