1

I have the following code:

$(document).ready(funcA);

function funcA(){
    funcB();
}

function funcB(){
    //some code
}

On the funcB, I want to know if it was called by the $(document).ready event or not.

It is any way I can do this?

Ricardo Rocha
  • 14,612
  • 20
  • 74
  • 130
  • 2
    Possible duplicate of [How do you find out the caller function in JavaScript?](http://stackoverflow.com/questions/280389/how-do-you-find-out-the-caller-function-in-javascript) – Robiseb Dec 14 '16 at 16:12
  • 6
    Why would you need to know such a thing? It sounds like an X/Y problem: You want to do X, you think knowing whether your function was called from `ready` is how to do that (Y), so you ask about Y. What's X? – T.J. Crowder Dec 14 '16 at 16:13
  • 2
    Pretty scary that you're thinking about basing the logic of a function execution based on it's callstack.... – Adam Jenkins Dec 14 '16 at 16:14
  • @Robiseb no that's not duplicate . it is not directly calling `funcB` – Mahi Dec 14 '16 at 16:14
  • Sorry, meant to say: The answer is "no, not reliably cross-browser." (Yes, you can on *some* browsers, if you want to rely on jQuery internals and accept all the concommitant hassles.) – T.J. Crowder Dec 14 '16 at 16:15
  • @T.J.Crowder I want this because it is a function that is used in diferentes places. The behavior chance if you call the function on document ready or if you call from anothers events – Ricardo Rocha Dec 14 '16 at 16:15
  • 3
    @RicardoRocha: Then give it a parameter that tells it which thing you want it to do, or split it into two functions. Sensing it from context is not a good idea. – T.J. Crowder Dec 14 '16 at 16:16
  • @RicardoRocha, so make it easy on yourself, and just make your function accept a boolean argument that is used to determine which behaviour to use. – Paul Dec 14 '16 at 16:19
  • @T.J.Crowder I understand want you are saying and of course that is the correct way to do it. But the problem is that i'm working in a huge webapplication and, for do that, I need to restructure a lot of code that will take a significant amount of time that I don't have in this moment. But I appreciate your help :) – Ricardo Rocha Dec 14 '16 at 16:21
  • 1
    @RicardoRocha doing it the "right" way will take *less* time, not more. Any reflective "solution" is going to be so error-prone or unportable as to be all but useless. Just grep through the code and change those functions. The ability to inspect the call stack is not guaranteed by the standard in any way I'm aware of. – Jared Smith Dec 14 '16 at 16:25
  • @JaredSmith I know what you are talking about. But you prefer have a big error in yours productions machine for 2 weeks or you prefer fix the issue now and latter restructure the code to became better? – Ricardo Rocha Dec 14 '16 at 16:28
  • @RicardoRocha that's a false dichotomy, because those aren't the options you have right now. Here is an exhaustive list of the options you have right now: 1) put a "fix" into production *that will not work* and will instantly generate *new* complaints/trouble tickets in addition to the ones you already have or 2) refactor the code. There isn't a way to do what you're asking. Period. – Jared Smith Dec 14 '16 at 16:31
  • @JaredSmith Thank you for your feedback. – Ricardo Rocha Dec 14 '16 at 16:37
  • @RicardoRocha: FWIW, I just tried the way I thought might work in some browsers (throwing and catching an error, looking at its `stack`, which is a non-standard string listing the call stack provided by some browser). But there just isn't enough information in there. The stack in `funcB` in my test is `funcB`/`HTMLDocument.funcA`/`j`/`k` (since this is a minified jQuery). – T.J. Crowder Dec 14 '16 at 16:43

1 Answers1

1

Don't do this

arguments.caller gives you the function that made the call.

You can compare it to a function, like so

if(arguments.caller == funcA)

since functions are types of variables. You can then do a loop that takes the arguments.caller of the arguments.caller and trace the route until you get null.

However, this is a non-standard feature and likely will not work

Instead

You might want to re-write all your functions so that they pass on a message to the funcB function, like this

What I mean is that you do this (or something with the same principle)

$(document).ready(function(){funcA("called by event listener")});

funcA(message){
   funcB(message);
}

funcB(message){
   if(message == "called by event listener") alert("Came from event listener");
}

Note that you do not have to name the arguments (in case you do not want to clutter everything), if you use arguments[arguments.length - 1]. arguments is an array of all arguments.

You could also try and mess around with the Function prototype, and try to make every function call pass along the last argument that it received, so that you do not have to do it yourself.

Max
  • 1,325
  • 9
  • 20
  • Only `arguments.callee` is not standard, as it's been explicitly _removed_ from the specs as of ES5. Moreover, it's been forbidden to be used. It may or may not work now but it's _more_ likely to not work the more modern the browser is. – VLAZ Dec 14 '16 at 16:23
  • Moreover, `callee` is useless for this. It'll be `funcB`. Perhaps you meant the never-standard `caller` property (which, despite never being standard, was disallowed in strict mode, and was never implemented widely). But even then, the caller of `funcB` is `funcA` whether `funcA` was called by `ready` or not. – T.J. Crowder Dec 14 '16 at 16:29
  • @T.J.Crowder you can do `x = arguments.callee;while(true){if(x.arguments.callee){x = arguments.callee}else{break;}}` – Max Dec 14 '16 at 16:32
  • @Max: Again: `callee` is the function that was **called**, not the function **calling it**. That loop makes no sense. – T.J. Crowder Dec 14 '16 at 16:36
  • Oh, oops, my bad, I'll edit it now and use `caller`. Thanks! – Max Dec 14 '16 at 16:37
  • There's no point. `caller` is a dead relic of the last century, and of no use here. – T.J. Crowder Dec 14 '16 at 16:38
  • @T.J.Crowder I have placed an alternate solution that will work much more reliably than `arguments.caller` – Max Dec 14 '16 at 16:49