Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private methods and fields

Tags:

javascript

I'm evaluating selfish and am wondering how I can declare private methods/fields?

like image 709
jgauffin Avatar asked Oct 08 '22 06:10

jgauffin


1 Answers

The usual way to do private functions is to use a function that your various "methods" close over, e.g. picking up their Dog example, change this:

// The basic Dog example
var Dog = Base.extend({
  bark: function() {
    return 'Ruff! Ruff!'
  }
});

To

// Adding a private function
var Dog = Base.extend((function(){
  function trulyPrivate() {
    console.log(this.bark());
  }

  return {
    bark: function() {
      return 'Ruff! Ruff!'
    },
    logBark: function() {
        trulyPrivate.call(this);
    }
  };
})());

Usage:

new Dog().logBark();  // logs "Ruff! Ruff!" using the truly private function behind the scenes

Re private fields, the usual way is to build anything that needs truly private fields from within your constructor function so they close over the (private) variables within the call to the constructor, a'la Crockford's pattern:

function Foo(arg) {
    var trulyPrivateData = arg;

    this.logIt = function() {
        console.log(trulyPrivateData);
    };
}

Usage:

var f = new Foo(42);
f.logIt(); // logs 42 even though there's no way, externally, to get that value from `f`

...selfish does away with the actual constructor function, but the initialize function should serve the same purpose:

var Dog = Base.extend({
  initialize: function(arg) {
    var woof = arg || 'Ruff! Ruff!';
    this.bark = function() {
        return woof;
    };
  }
});

Now, you can't set the woof (except at construction time, because we did that on purpose), you can only retrieve it from bark. E.g., it's truly private (other than that we've explicitly allowed bark to return it).

If you get into the technical details of this, these articles from my blog may (or may not) be useful, since when you get into private functions and such, you typically have to start managing this:

  • Mythical Methods
  • You must remember this
  • Private Methods in JavaScript (seriously in need of an update/rewrite)

And if you want another thing to evaluate, there's my Lineage project, which is similarly pure prototypical inheritance, but with easy access to parent object properties, functions, etc. and a syntax that actively encourages private scopes for this sort of thing.

like image 196
T.J. Crowder Avatar answered Oct 12 '22 20:10

T.J. Crowder