Search code examples
javascriptprivate-members

Hiding class methods by using .call/.apply


Can someone explain what this excerpt from Single Page Apps in Depth means?

A common pattern for classes (e.g. objects instantiated from a prototype) is to simply mark class methods as private by starting them with a underscore. You can properly hide class methods by using .call/.apply to set "this", but I won't show it here; it's a minor detail.

I think it suggests there is a way to actually make 'private' JavaScript methods actually inaccessible instead of the convention of just marking them with an underscore, but I can't imagine what an implementation would look like, nor how it would be used.


Solution

  • var Treasure = function(){  
      function locate(){
        return this.x * this.y + 31337;
      }
    
      function Treasure(x, y){
        this.x = x;
        this.y = y;
      }
    
      Treasure.prototype.find = function find(){
        return locate.call(this);
      };
    
      return Treasure;
    }();
    

    locate is a shared private function for the constructor and prototype methods. Using call it can act like a method and utilize this.

    A more complete implementation of this concept is that of interface objects and implementation objects. Instead of having a few random functions-as-methods (similar to locate above) you actually create a whole class that is private. Every external creation of the interface results in two objects crated: the public shell interface and the private implementation object. This allows you to expose an interface that provides a different, perhaps easier to use, API publicly. Or can allow you to reuse single private implementation objects for entire groups of interface objects.

    This is actually how the DOM is specified to work (usually not implemented in js though). The interface objects (element and node objects for example) are specifically required to wrap the underlying implementation that actually does the word. The exposed objects are little more than shells that forward property access and method invocation.

    Dom.js is a full blown DOM implementation made in js. An interesting technique I got acquainted with while working in it was completely automated generation of public interfaces. This is the purpose of IDL: the public API is literally generated automatically, leaving only the private implementation to actually be created. What this really means its possible to create things like this without consulting a human: https://github.com/Benvie/svgstuff/blob/master/lib/defs.js