How to find out which path is followed by a function in js

Asked

Viewed 478 times

5

Explaining my scenario, using emberjs, and it encapsulates each Component within a Controller that will be encapsulated inside a Router, and still has a scheme of Model, Mixins, Helpers, when there is no component, or addon, or mixin chatting with another component, addon, mixin (welcome to modern javascript).... Sometimes it is very difficult to debug the code, know the javascript path path, the scope in which such a function or method was called, using the console.debug(); I can get the current scope of the function, but it’s hard to know where that function was called from. Is there any method or javascript mode to find out all the way the function has traveled to reach a certain point?

Exemplifying:

function A(){
  B();
}

function B(){
  a.teste();
}

function C(){
  /*Descobrir como o javascript chegou até aqui*/
  console.log("Hellor Weird World!");
  console.debug();
}

var a = {
  teste: function(){
    C();
  }
}

A();

  • 2

    This would be very useful, I do via element inspector, of course it already has to be open before the function perform, but the big problem is when they use .call or .apply, as jQuery does, there is almost impossible to find :/ (I don’t know why)

  • 1

    A strange way, but that works is console.log(new Error().stack);, which is basically the suggested in this answer on Soen

1 answer

2


There is a way to find out who called the function, through the local variable arguments. Note that this method only works if you are not using it Strict mode, that is, the file cannot contain 'use strict';

Example:

function Hello()
{
    alert("O nome da função que chamou é " + arguments.callee.caller.name);
}

function Main() {
    Hello();
}

Main();

This execution will show on Alert "The name of the called function is Main".

However, you need to track the full path and not just the last "Caller". In this case we would have to recursively capture the callers, until they are null. Logic would be something similar to this:

function Hello()
{
    rastrear();
}

function Main() {
    Hello();
}

function Main2() {
    Main();
}

function rastrear() {
    var trace = '';
    var haveTrace = true;

    var caller = arguments.callee.caller;

    trace = caller.name + ' -> ';

    while(haveTrace) {
        if(caller.caller) {
            trace = caller.caller.name + ' -> ' + trace;
            caller = caller.caller;
        } else {
            haveTrace = false;
        }
    }

    console.log(trace);
}

Main2();

This will print on the console the result "Main2 -> Main -> Hello -> ". But beware! Using this function in recursive functions can cause an infinite looping!


Another great option would be to use the function console.trace();. Then it would be something like this:

function Hello()
{
    console.trace();
}

function Main() {
    Hello();
}

function Main2() {
    Main();
}

Main2();

This will result in something like this on the console:

console.trace
Hello @ VM197:3
Main @ VM197:7
Main2 @ VM197:11

In addition there are other programmable possibilities, but it is already a great starting point.

  • to use the track() I would have to declare the function within my system, correct? Would it work well with multiple js files that talk to each other in the same project? I thought it was cool console.trace()! I didn’t know =)

  • It does work. But in your case, in a framework, a lot happens behind the scenes. He may end up "tracking", executions of ancestral class functions such as Controller, Component, Router and etc... has this factor. About the console.trace(), really is a great option, and eventually should fall into the situation I quoted from the tracking too.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.