too much php
too much php

Reputation: 91058

__LINE__ equivalent in Javascript

Is there any way to get the source line number in Javascript, like __LINE__ for C or PHP?

Upvotes: 20

Views: 9507

Answers (8)

Bekir
Bekir

Reputation: 56

@kurdtpage's answer is fine. I used it for my Chrome browser extension. As he said, It doesn't work in Firefox. I inspected the code and adjusted it. Works fine.

Object.defineProperty(globalThis, "__LINE__", {
    get: _ => parseInt(new Error().stack.trim().split("\n").at(-1).split(":").at(-2), 10)
});

I used globalThis because it seems more reliable for cross-browser extensions. Removed the offset because I don't see it does a think. I used .trim() to get rid of the empty line that comes sometimes, .at(-1) to get the last line, .at(-2) to get the line number properly. After the .split(":") the consistent part is the end.

These are some last line examples. They are from Chrome extension, Firefox extension, JSFiddle and random website Devtools:

at chrome-extension://ojeimgnebnoloecdikhnjpagoggeaikg/js/test.js:250:27
at @moz-extension://8aeed981-e785-422b-8918-4adb8a0d8ef4/js/test.js:248:27
at https://fiddle.jshell.net/_display/?editor_console=true:139:27
at <anonymous>:30:27

Upvotes: 0

kurdtpage
kurdtpage

Reputation: 3221

You can use this in vanilla JS:

function getLine(offset) {
    var stack = new Error().stack.split('\n'),
        line = stack[(offset || 1) + 1].split(':');
    return parseInt(line[line.length - 2], 10);
}

Object.defineProperty(window, '__LINE__', {
    get: function () {
        return getLine(2);
    }
});

You will now have access to the global variable __LINE__

Upvotes: 4

ET
ET

Reputation:

There is one workaround.

Usually the __ LINE __ combined with the __ FILE __ is used for marking a locations in code and the marking is done to find that location later.

However, it is possible to achieve the same effect by using Globally Unique Identifiers (GUID-s) in stead of the __ LINE __ and __ FILE __. Details of the solution reside in the COMMENTS.txt of a BSD-licensed toolset that automates the process.

Upvotes: 0

MIkee
MIkee

Reputation: 942

I think preprocessing makes more sense, in that it adds no runtime overhead. An alternative to the C preprocessor is using perl, as in the 2 step procedure below:

1 – add “Line # 999 \n” to each line in the script that you want numbered, e.g.,

  alert ( "Line # 999 \n"+request.responseText);

2 – run the perl below:

cat my_js.js | perl -ane "{ s/Line # \d+ /Line # $. /; print $_;}" > C_my_js.js; mv  C_my_js.js  my_js.js

Upvotes: 1

liori
liori

Reputation: 42357

You can try to run C preprocessor (f.e. cpp from GNU Compiler Collection) on your javascript files -- either dynamically with each request or statically, by making this operation be applied every time you change your javascript files. I think the javascript syntax is similar enough for this to work.

Then you'd have all the power of C preprocessor.

Upvotes: 2

kjfletch
kjfletch

Reputation: 5494

A __LINE__ in C is expanded by a preprocessor which literally replaces it with the line number of the current input. So, when you see

printf("Line Number: %d\r\n", __LINE__);

the compiler sees:

printf("Line Number: %d\r\n", 324);

In effect the number (324 in this case) is HARDCODED into the program. It is only this two-pass mechanism that makes this possible.

I do not know how PHP achieves this (is it preprocessed also?).

Upvotes: 2

David Hanak
David Hanak

Reputation: 10984

There is a way, although more expensive: throw an exception, catch it immediately, and dig out the first entry from its stack trace. See example here on how to parse the trace. The same trick can also be used in plain Java (if the code is compiled with debugging information turned on).

Edit: Apparently not all browsers support this. The good news is (thanks for the comment, Christoph!) that some browsers export source file name and line number directly through the fileName and lineNumber properties of the error object.

Upvotes: 10

Greg
Greg

Reputation: 321786

The short answer is no.

The long answer is that depending on your browser you might be able to throw & catch an exception and pull out a stack trace.

I suspect you're using this for debugging (I hope so, anyway!) so your best bet would be to use Firebug. This will give you a console object; you can call console.trace() at any point to see what your programme is doing without breaking execution.

Upvotes: 6

Related Questions