Accessing line number in V8 JavaScript (Chrome & Node.js)

前端 未结 2 1256
心在旅途
心在旅途 2020-11-30 18:11

JavaScript developers who have spent time in languages like C often miss the ability to use certain types of introspection, like logging line numbers, and what method the cu

相关标签:
2条回答
  • 2020-11-30 18:25

    The problem with the accepted answer, IMO, is that when you want to print something you might be using a logger, and when that is the case, using the accepted solution will always print the same line :)

    Some minor changes will help avoiding such a case!

    In our case, we're using Winston for logging, so the code looks like this (pay attention to the code-comments below):

    /**
     * Use CallSite to extract filename and number, for more info read: https://v8.dev/docs/stack-trace-api#customizing-stack-traces
     * @returns {string} filename and line number separated by a colon
     */
    const getFileNameAndLineNumber = () => {
        const oldStackTrace = Error.prepareStackTrace;
        try {
            // eslint-disable-next-line handle-callback-err
            Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace;
            Error.captureStackTrace(this);
            // in this example I needed to "peel" the first CallSites in order to get to the caller we're looking for
            // in your code, the number of stacks depends on the levels of abstractions you're using
            // in my code I'm stripping frames that come from logger module and winston (node_module)
            const callSite = this.stack.find(line => line.getFileName().indexOf('/logger/') < 0 && line.getFileName().indexOf('/node_modules/') < 0);
            return callSite.getFileName() + ':' + callSite.getLineNumber();
        } finally {
            Error.prepareStackTrace = oldStackTrace;
        }
    };
    
    0 讨论(0)
  • 2020-11-30 18:35
    Object.defineProperty(global, '__stack', {
      get: function(){
        var orig = Error.prepareStackTrace;
        Error.prepareStackTrace = function(_, stack){ return stack; };
        var err = new Error;
        Error.captureStackTrace(err, arguments.callee);
        var stack = err.stack;
        Error.prepareStackTrace = orig;
        return stack;
      }
    });
    
    Object.defineProperty(global, '__line', {
      get: function(){
        return __stack[1].getLineNumber();
      }
    });
    
    console.log(__line);
    

    The above will log 19.

    Combined with arguments.callee.caller you can get closer to the type of useful logging you get in C via macros.

    0 讨论(0)
提交回复
热议问题