2

I have the following situation:

  • a main script with commons methods
  • several other scripts which are using them

(function() {
    window.mainMethod = function(param) {
        //...
        //console.log("I'm calling this method from context "+myContext.name); [CAN'T DO]
        console.log(arguments.callee.caller.name);
    }
})();

// Object A
(function() {
    var myContext = {};
    myContext.name = "context A";
    myContext.fn = function fnA() {
        window.mainMethod("param A1");
        // ...
        window.mainMethod("param A2");
        // ...
        window.mainMethod("param A3");
        // etc...
    }();
})();

// Object B
(function() {
    var myContext = {};
    myContext.name = "context B";
    myContext.fn = function fnB() {
        window.mainMethod("param B1");
        // ...
        window.mainMethod("param B2");
        // ...
        window.mainMethod("param B3");
        // etc...
    }();
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

What I'm trying to do is to log in my mainMethod the context where I'm calling that method from.

First thing I camed up with was to add a parameter to each call :

window.mainMethod("some parameter 1", myContext);

BUT since this is only for log purposes (not functional) and I have thousands of these occorrences to modify, i would like to avoid that.

So I thought maybe there is a way to access to myContext object through the callee.caller property, but this is where I went so far.

window.mainMethod = function(parameter) {
    //console.log("I'm calling mainMethod from context " + myContext.name);
    console.log(arguments.callee.caller.name);
}

This will print out the function name (fnA), but still can't access the object where the function is stored (myContext).

Any suggestion?


ps: i'm also open for workarounds like, i don't know, binding some hidden property to the function and then retrieve it with arguments.callee.caller.myHiddenProperty ... is it possible?

pumpkinzzz
  • 2,907
  • 2
  • 18
  • 32
  • 1
    According to https://stackoverflow.com/questions/9679053/is-it-possible-to-get-the-caller-context-in-javascript you cannot access caller context this way. – Andrzej Smyk Oct 03 '17 at 10:26
  • 3
    Possible duplicate of [How do you find out the caller function in JavaScript?](https://stackoverflow.com/questions/280389/how-do-you-find-out-the-caller-function-in-javascript) – freedomn-m Oct 03 '17 at 10:40
  • @freedomn-m that's not the question here – pumpkinzzz Oct 03 '17 at 10:42
  • @GhassenLouhaichi i'm sorry but i seriously don't know what are you talking about.. i mean it – pumpkinzzz Oct 03 '17 at 10:52

2 Answers2

1

The closest I think you're going to get is to explicitly change the context using call

(function(){
  window.mainMethod = function(param){
        //...
        //console.log("i'm calling this method from context "+myContext.name); [CAN'T DO]
        console.log(this.name, arguments.callee.caller.name, param);
    }
})();


// Object A
(function(){
   var myContext = {};

   myContext.name = "context A";
   myContext.fn = function fnA(){
      window.mainMethod.call(myContext,"param A1");
      // ...
      window.mainMethod.call(myContext,"param A2");
      // ...
      window.mainMethod.call(myContext,"param A3");
      // etc...
  }();

})();

// Object B
(function(){
   var myContext = {};

   myContext.name = "context B";
   myContext.fn = function fnB(){
      window.mainMethod.call(myContext,"param B1");
      // ...
      window.mainMethod.call(myContext,"param B2");
      // ...
      window.mainMethod.call(myContext,"param B3");
      // etc...
  }();

})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • yeah, i thoght that too, but i still have to modify every single occurrence of these calls, which is what i'm trying to avoid here – pumpkinzzz Oct 03 '17 at 10:39
1

If you don't want to change the thousands of calls to mainMethod you have, you need to alter the functions that call it (fn). The solution is to keep fn as a function instead the result of a function like you have currently, then add the context to it that you can later invoke from inside the mainMethod function :

(function() {
    window.mainMethod = function() {
        // will print the context that has been added to the function object
        console.log(arguments.callee.caller.context);
    }
})();

// Object A
(function() {
    var myContext = { name: 'A' };
    myContext.fn = function fnA() {
        window.mainMethod();
    // notice that I removed the `()` to keep `fn` as a function inside `myContext`
    };
    // now add the context inside the function object
    myContext.fn.context = myContext;
    // then just call it
    myContext.fn();
})();
M0nst3R
  • 5,186
  • 1
  • 23
  • 36
  • thanks, this is a nice workaround even if i have to manually set that property on every function (but still better then changing all the calls) – pumpkinzzz Oct 03 '17 at 11:16
  • This is definitely a bit hacky, but it serves the purpose if you do not want the change the numerous calls. But in a later time, you would benefit alot from refactoring all the code to use classes. – M0nst3R Oct 03 '17 at 11:18