1

There is a good generalized method for defining private and protected properties and methods in Javascript, here on the site. However, the current version of Prototype (1.6.0) doesn't have a built-in way to define them through its Class.create() syntax.

I'm curious what the best practices are when developers want to define private and protected properties and methods when using Prototype. Is there a better way than the generic one?

aynber
  • 22,380
  • 8
  • 50
  • 63
Eric Nguyen
  • 40,312
  • 4
  • 25
  • 31

3 Answers3

2

There's a discussion here in Prototype's lighthouse that shows that explains why you can't get this effect with Prototype's Class.create.

TML
  • 12,813
  • 3
  • 38
  • 45
  • Can you give me access to this link? I agree with your opinion but I would like to see the discussion, but it requires a login. It would not allow me to use my Google login... – Charles Robertson Feb 16 '16 at 22:20
  • 1
    [Here](http://web.archive.org/web/20081204014823/http://prototype.lighthouseapp.com/projects/8886/tickets/152-implement-private-variables-for-classes) is a link to the discussion as captured by archive.org. – TML Feb 17 '16 at 08:33
  • Thanks. This is a very interesting discussion. I would love to see this implemented. I have had a detailed look at the patch, and it looks pretty solid. I will do some testing with the patch merged into prototype-1.7.3.js and see if this is reliable... – Charles Robertson Feb 18 '16 at 14:49
2

What you can do is using local variables in your constructor function (initialize) for prototype and then creating a closure that will access/expose this variable to your public methods.

Here's a code example:

// properties are directly passed to `create` method
var Person = Class.create({
   initialize: function(name) {
      // Protected variables
      var _myProtectedMember = 'just a test';

      this.getProtectedMember = function() {
         return _myProtectedMember;
      }

      this.name = name;
   },
   say: function(message) {
      return this.name + ': ' + message + this.getProtectedMember();
   }
});

Here's Douglas crockford theory on the subject.

http://www.crockford.com/javascript/private.html

Christophe Eblé
  • 8,071
  • 3
  • 33
  • 32
  • Awesome. Thanks. I voted up TML's answer as well, since the link he includes has a full discussion on this topic, and reveals why other (cleaner-looking) implementations don't work. – Eric Nguyen May 24 '09 at 08:41
  • 1
    @SleepyCod : how would you define a totally encapsulated private variable, that is, one that does not have a setter or getter? Your example has a getter so other class methods can get the field, but that exposes the field to the outside world. – JoJo Dec 29 '11 at 20:10
  • @Christophe Eblé This is not a private method. Use var getProtectedMember = function(){... However, it is then not possible to access this method from within other methods, but at least it cannot be accessed from outside the class. I am researching if it is possible to allow a method to be accessible from within but not outside... – Charles Robertson Feb 16 '16 at 22:18
0

The key is to add the public methods as closures, as in the example below:

 Bird = Class.create (Abstract,(function () {
    var string = "...and I have wings"; //private instance member
    var secret = function () {
        return string;
    } //private instance method
    return {
        initialize: function (name) {
            this.name = name;
        }, //constructor method
        say: function (message) {
            return this.name + " says: " + message + secret();
        } //public method
    }
})());

Owl = Class.create (Bird, {
    say: function ($super, message) {
        return $super(message) + "...tweet";
    } //public method
})

var bird = new Bird("Robin"); //instantiate
console.log(bird.say("tweet")); //public method call

var owl = new Owl("Barnie"); //instantiate
console.log(owl.say("hoot")); //public method call inherit & add
Charles Robertson
  • 1,760
  • 16
  • 21