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
4
  • Is there a reason to do it? I mean if someone calls functions he shouldn't, he can also edit your validation away Commented Sep 5, 2012 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 Commented Sep 5, 2012 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 Commented Sep 5, 2012 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. Commented Jan 30, 2013 at 7:20

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is the sort of answer I was looking for.
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

5 Comments

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?
Can you give an example of the type of scoping issues which would get around this then ?
as far as I understand the private members are not accessible from functions which are added to the prototype outside of the constructor.
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.
I mean like the 3rd code block in this stack exchange post: stackoverflow.com/questions/1041988/… due to the lexical scoping rules of javascript, "private_member" would not be defined in the member "public_method"
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.