Tim Seguine
Tim Seguine

Reputation: 2914

Using tricks to enforce private inheritance in javascript

So I came up with something sort of hackish to check and see if a function is called from within the object itself. Can someone give me some good reasons not to do something like this?

function Poo(){
this.myFunc=function(){
    for(x in this)
    {
           if (this.myFunc.caller==this[x]) {
               alert(this.myFunc.caller==this[x]);
               return;}
     }
      alert(false);             
    }
    this.myFunc2=function(){this.myFunc();}
}
var mine=new Poo();
mine.myFunc(); //calling directly not allowed prints false
mine.myFunc2(); //called from a member function allowed prints true

Upvotes: 0

Views: 125

Answers (3)

midu
midu

Reputation: 1707

You can do whatever you want, however, I can show you a case where you method doesn't work:

function Poo(){
  this.myFunc = function () {
    for(x in this) {
      if (this.myFunc.caller == this[x]) {
        console.info('internal call, accepted');
        return;
      }
    }
    console.error('no external calls allowed');
  };

  this.myFunc3 = function () {
    var self = this;
    // this is a standard way of
    // passing functions to callbacks
    // (eg, ajax callbacks)
    this.myFunc4(function() {
      self.myFunc();
    });
  }

  this.myFunc4 = function (callback) {
    // do stuff...
    callback();
  };
}

var mine = new Poo();

mine.myFunc3();

myFunc3 is within the object, so I assume you would expect the call to myFunc in the callback it gives to myFunc4 (also in the object) to work. However, caller doesn't do well with anonymous functions.

Also, iterating through the entire instance methods and attributes while comparing functions is definitely not the "Object Oriented" way of doing it. Since you're trying to emulate private methods, I'm assuming that OO is what you're looking for.

Your method is not taking any advantage of the features JS offers, you're just (re)building existing functionality in an inelegant way. While it may be interesting for learning purposes, I wouldn't recommend using that mindset for shipping production code.

There's another question on stackover that has an answer that you may be interested in: Why was the arguments.callee.caller property deprecated in JavaScript?

edit: small change on how I call myFunc from the callback, in the anonymous function this was not the instance.

Upvotes: 1

Mark Broadhurst
Mark Broadhurst

Reputation: 2695

Why not use something like the module pattern to hide the implementation of your "private" methods.

var poo = function(){
   var my = {},
       that = {};

   my.poo = function() {
      // stuff
   };
   that.foo = function(){
      my.poo(); //works
      // more stuff
   };
   return that;
};
poo.foo(); // works
poo.poo(); // error

Upvotes: 0

Hans Hohenfeld
Hans Hohenfeld

Reputation: 1739

I cant't give you a good reason not to do this, but a lot easier solution.

function Poo() {
     var myFunc = function() {
          alert('myfunc');
     };

     this.myFunc2 = function() {
         myFunc();
     }
}

var mine = new Poo();
var mine.myFunc();  // Won't work
var mine.myFunc2(); // Will work

Upvotes: 0

Related Questions