0

I have functions in JavaScript that need to check that the function running it is, indeed, the correct function (ex, needs the function something.stuff.morestuff.coolFunction to have called it or it wont run). I've tried getting Function.caller, but this only returns the function itself, and no way to determine which objects it is inside of.

Given the following setup:

function helloWorld(){
    if(/* the exact path to the calling function */ === 'greetings.happy.classic.sayhello'){
        console.log('Hello World');
    }else{
        console.log(/* the path from earlier */ + ' not allowed.');
    }
}

greetings = {
    happy: {
        classic: {
            sayHello: function(){ helloWorld(); }
            sayBye: function(){ helloWorld(); }
        }
    },
    angry: {
        sayHello: function(){ helloWorld(); }
    },
    simple: [
        function(){ helloWorld(); }
    ]
}
function sayWords(){
    helloWorld();
}

What I'm trying to accomplish would look like this:

greetings.happy.classic.sayHello(); // => Hello World!
greetings.happy.classic.sayBye();   // => greetings.happy.classic.sayBye not allowed.
greetings.angry.sayHello();         // => greetings.angry.sayHello not allowed.
greetings.simple[0]();              // => greetings.simple[0] not allowed.
sayWords();                         // => sayWords not allowed.
helloWorld();                       // => null not allowed.
// not sure what would come out of this, so i put null on that one

Here's the question in one neat little package:

How would I find the exact object path (i.e. greeting.happy.classic.sayHello) of the calling function? Function.caller.name just returns the name of the function, which is not enough. I need the full tree of the calling function's location.

This feels like a complex issue, so thank all for your help.

MineAndCraft12
  • 671
  • 5
  • 15
  • The object that invokes the function is referred with the `this` keyword within that function. Beyond that for the nested parents, I don't think you can do it and i don't think there is a need for that. You could either wire up your algorithm such that the decision stage whether to invoke a function or not isn't placed downstream or you may try passing arguments to enable the function to decide what to do. I am pretty sure you can find tons of ways to achieve that. – Redu Jul 21 '16 at 16:04
  • Using `this` in a function, even if called by a different function, does not access the caller's `this` scope; only the `this` scope of the function itself. `this` reffers to the object in which your function resides, not the one that called it. – MineAndCraft12 Jul 21 '16 at 16:16

2 Answers2

0

Well, you seem to be trying to find out parent's reference in the child object. This is not possible. Check out this post Javascript Object get parent

Community
  • 1
  • 1
DivineCoder
  • 702
  • 5
  • 11
  • This looks like it's true from the reference of the calling object itself, but I would have thought that there's some way to get the full path to the caller function instead of just.... the name of the caller function. I'll keep waiting to see if anything comes up, but so far it's looking like I may need to find a different method of doing this besides tracking the caller... – MineAndCraft12 Jul 21 '16 at 16:35
  • I've decided to actually just rely on a prompt to the user asking for permission, as I've just remembered that any function can invoke the function that's allowed to invoke the protected one, if that makes sense. User permission seems a bit more reliable as well. – MineAndCraft12 Jul 21 '16 at 17:03
0

I think you could use new Error().stack to analyse where the call comes from.

Hopefully you're aware that any preprocessor/uglyfier/bundler is more than likely to break your approach ...

alebianco
  • 2,475
  • 18
  • 25
  • This was a very good idea; however when I tried inserting this into one of my other projects and checking the console (the project i tried your solution on is unrelated to this one), I got `Object.delete` in the stack instead of the actual path of `apps.savemaster.vars.delete`... – MineAndCraft12 Jul 21 '16 at 16:29
  • yes you're right, once you return an object it would pop the frame from the stack, so it's not possible to track the object stack. You'd have to manually track parent/child relationships of objects and then use that ... – alebianco Jul 22 '16 at 08:10