2

Consider these script fragments.

<script data-name="script1">
    foo();
</script>

<script data-name="script2">
    foo();
</script>

<script>
    function foo(){
//      console.log(arguments.?);
    }
</script>

Is there a way to find out which script function foo was called from the line denoted by the "//"?

7
  • 1
    The answer will be "no". Commented Nov 20, 2013 at 19:05
  • 4
    No, as functions don't carry information about the script tag they were defined within. What is your use-case with this? Perhaps you just need a different approach to accomplish your goal Commented Nov 20, 2013 at 19:05
  • @RobM. I have a 1:1 relation between a script and an object, and was hoping to be able to have a global, transparent function to map. (Rather than each script having to map itself.) Commented Nov 20, 2013 at 19:14
  • I think I understand what you are trying to accomplish. Is each script tag actually calling a function or defining an object? If it's an object you elaborate with a more concrete example? Commented Nov 20, 2013 at 19:19
  • @RobM. Let's say the main script is a database wrapper, and for each script it makes a table. foo is a function to run an operation on the correct table. Ideally I'd like it so a third party making a script wouldn't have to explicitly identify with each function call. Commented Nov 20, 2013 at 19:24

2 Answers 2

2

As already mentioned in the comments, the way you present it, this is not possible, it only works if the function foo is called from a function, which then of course has to be a different function for each script, then you can use

console.log(arguments.callee.caller.name)

That will give you the name of the function that called your function foo.

Edit: and really, if it's important to know from where the script was called, just use an argument, like function foo(caller){, which indicates how the function was called, that's much safer than relying on the arguments.callee.caller thing.

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

4 Comments

I was thinking of wrapping, but it just returns the anonymous function. (I.e. name="") As for the edit, having to identify for every function call out is precisely why I wanted to make it transparent.
Warning: The 5th edition of ECMAScript (ES5) forbids use of arguments.callee() in strict mode. See why
I completely agree Oriol, that's why I would only use the arguments.callee for debugging of your scripts during development (which I assumed in this case, as it was only used for a console log). As for the anonymous functions, yeah that won't work, and the only way to do the identification then is by looking at some unique property of the objects that you are working with, or still, by using an argument in the function call.
The problem with passing the caller as an argument, though, is that it is unreliable. One conceivable use case of determining the caller could be some sort of access control (i. e. to forbid scripts from particular sites access to the function(s) in question), and in order to bypass that, the script in question could attempt to forge the caller argument.
0

Ok, I figured it out, this will grab the script data-name attribute

function foo() {
    var parentScript = document.body.lastChild;
    console.log(parentScript.getAttribute('data-name'));
}

To get it to work I had to define the foo function above the calls to it, but I'm sure some playing around with it could resolve that.

6 Comments

Not sure why this was downvoted...jQuery dependency? Would love some elaboration on that
Wasn't me, but whilst that's probably technically right per se, it only works as the DOM is loaded. Once loaded, it will always return the last script.
Fair enough, well this was my best guess; the link that @zzzzBov posted is probably a better solution
I downvoted it for 1) unnecessary, unspecified dependency which Q was not tagged for, 2) it may not work if scripts are being inserted into the body (using something like JSONP; the same problem exists in the question zzzzBov linked). See also stackoverflow.com/questions/14410748
Again, that's fair; but just to be clear: OP didn't state that scripts were going to be inserted after DOM loaded and given the top-down processing of their example, a simple removal of the jQ dependency would accomplish the goal as stated.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.