0

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
Tim Seguine
  • 2,887
  • 25
  • 38
  • Is there a reason to do it? I mean if someone calls functions he shouldn't, he can also edit your validation away – Wurstbro Sep 05 '12 at 15:23
  • @Wurstbro I realize there are ways around it, The point of it is to provide a more forceful hint that the class is being used incorrectly than naming functions starting with an underscore – Tim Seguine Sep 05 '12 at 15:26
  • @Tim you shouldn't care if the class is used incorrectly if you have provided good api documentation and use cases. IMHO this kind of tricks are useless. If he really wants to use the class outside the specs he will do it regardless of your hack – Vlad Balmos Sep 05 '12 at 15:39
  • I don't necessarily understand the downvote. I wasn't suggesting actually doing this. Javascript's object model doesn't have good support for data hiding in my opinion, and 90% of javascript programming seems to be typing lengthy idioms. Result: frustration. – Tim Seguine Jan 30 '13 at 07:20

3 Answers3

1

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.

Community
  • 1
  • 1
midu
  • 1,589
  • 1
  • 9
  • 14
0

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
Hans Hohenfeld
  • 1,729
  • 11
  • 14
  • I am aware of this method actually. This solution doesn't handle certain types of scoping though as far as I know. OR am I wrong? – Tim Seguine Sep 05 '12 at 15:25
  • Can you give an example of the type of scoping issues which would get around this then ? – Mark Broadhurst Sep 05 '12 at 15:26
  • as far as I understand the private members are not accessible from functions which are added to the prototype outside of the constructor. – Tim Seguine Sep 05 '12 at 15:29
  • As long as people use `new` otherwise `this` becomes the `global object` and then you can call `myFunc` but that's assuming `this` can be global with out causing an error. – Mark Broadhurst Sep 05 '12 at 15:31
  • I mean like the 3rd code block in this stack exchange post: http://stackoverflow.com/questions/1041988/better-way-to-access-private-members-in-javascript due to the lexical scoping rules of javascript, "private_member" would not be defined in the member "public_method" – Tim Seguine Sep 05 '12 at 15:34
0

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
Mark Broadhurst
  • 2,675
  • 23
  • 45