Reputation: 91058
Is there any way to get the source line number in Javascript, like __LINE__
for C or PHP?
Upvotes: 20
Views: 9507
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
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
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
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
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
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
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
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