Làm cách nào để xác định số dòng hiện tại trong JavaScript?


Câu trả lời:


69

var thisline = new Error().lineNumber

Nếu điều đó không hoạt động trong bất kỳ môi trường nào bạn đang sử dụng, bạn có thể thử:

var stack = new Error().stack

Sau đó, tìm kiếm số dòng trong ngăn xếp.


3
Sẽ không hoạt động trong IE, thuộc lineNumbertính không tồn tại trên các đối tượng lỗi. Cũng không stack:-)
Andy E

1
có một số dòng ở đâu đó trên IE. Tôi biết điều này bởi vì khi javascript của tôi ném ra một lỗi được cho là nó nằm trên một dòng có số lớn hơn 100 triệu.
Malfist

i dont khá có được con số chính xác, nó 1350 khi nó phải được 1250.
Fzs2

1
Vấn đề: nếu bạn đang sử dụng PHP, thì "mã nguồn" mà javascript nhìn thấy không phải là mã nguồn ban đầu, vì vậy nó có số dòng sai. (Đó có lẽ là những gì đang xảy ra với Hermann.) Có ai biết cách làm cho javascript nhìn thấy số dòng mã nguồn PHP ban đầu không? Giải pháp có thể liên quan đến một số loại tạo "bản đồ nguồn", nhưng tôi không thể tìm thấy cách thực hiện. Chắc chắn đây là một vấn đề đã được giải quyết, phải không ??
Dave Burton

Lưu ý: đôi khi số ngăn xếp / dòng không có sẵn khi đối tượng Lỗi được tạo, chỉ khi đối tượng này được ném ra, chẳng hạn như trong Google Apps Script - trong trường hợp đó, hãy xem câu trả lời này để biết giải pháp.
user202729

38

Bạn có thể dùng:

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

test();

1
Cho đến nay, giải pháp đơn giản nhất và nó thậm chí còn hoạt động trên MS Edge.
Nguy hiểm

27

Di động hơn một chút giữa các trình duyệt và phiên bản trình duyệt khác nhau (sẽ hoạt động trên Firefox, Chrome và IE10 +):

function ln() {
  var e = new Error();
  if (!e.stack) try {
    // IE requires the Error to actually be throw or else the Error's 'stack'
    // property is undefined.
    throw e;
  } catch (e) {
    if (!e.stack) {
      return 0; // IE < 10, likely
    }
  }
  var stack = e.stack.toString().split(/\r\n|\n/);
  // We want our caller's frame. It's index into |stack| depends on the
  // browser and browser version, so we need to search for the second frame:
  var frameRE = /:(\d+):(?:\d+)[^\d]*$/;
  do {
    var frame = stack.shift();
  } while (!frameRE.exec(frame) && stack.length);
  return frameRE.exec(stack.shift())[1];
}

Cảm ơn. Tôi đã điều chỉnh đề xuất của bạn cho điều này: stackoverflow.com/a/37081135/470749
Ryan

1
Nếu bạn điều chỉnh regex, bạn có thể trả về cả số dòng và số cột: var frameRE = /:(\d+:\d+)[^\d]*$/;điều này hữu ích hơn nhiều, đặc biệt khi JS được rút gọn thành một dòng dài.
Quinn Comendant

Cảnh báo, không hoạt động trong tập lệnh ViolentMonkey dành cho Chrome - bạn sẽ nhận được một con số không có thật, không biết tại sao.
hanshenrik 14/02/19

5

Bạn có thể thử phân tích cú pháp nguồn của một hàm để tìm kiếm một số dấu.
Đây là một ví dụ nhanh (vâng, nó hơi lộn xộn).

function foo()  
{       
    alert(line(1));
    var a;
    var b;      
    alert(line(2));
}   
foo();

function line(mark)
{
    var token = 'line\\(' + mark + '\\)';       
    var m = line.caller.toString().match(
        new RegExp('(^(?!.*' + token + '))|(' + token + ')', 'gm')) || [];
    var i = 0;
    for (; i < m.length; i++) if (m[i]) break;
    return i + 1;
}

3

Chèn đoạn mã sau vào mã của bạn:

console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);

thay thế tên giao thức khi cần thiết (ví dụ: "http:")
crishushu

1
Tôi không thể làm cho nó hoạt động. Tôi hiểu TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null.
Ryan

2

Bạn co thể thử:

window.onerror = handleError;
function handleError(err, url, line){
    alert(err + '\n on page: ' + url + '\n on line: ' + line);
}

Sau đó, hãy ném một lỗi vào nơi bạn muốn biết (không quá mong muốn, nhưng nó có thể hữu ích nếu bạn đang gỡ lỗi.

Lưu ý: window.onerrorkhông được xác định / xử lý trong WebKit hoặc Opera (lần cuối cùng tôi đã kiểm tra)


1
Lưu ý rằng window.onerror không hoạt động trong webkit: bug.webkit.org/show_bug.cgi?id=8519
Annie

1
Hấp dẫn. Bạn thậm chí có thể tạo một hàm đặc biệt throwAndResume(resumeFunction);để lưu trữ lại resumeFunction, xử lý lỗi và ghi lại thông tin chi tiết trong trình xử lý lỗi, sau đó gọi ResumeFunction để tiếp tục chương trình của bạn.
z5h

0

Hoàn toàn không thể lấy số dòng ra khỏi Error.stack, vì trong Angular, số dòng là số dòng của mã đã biên dịch. Nhưng người ta có thể lấy thông tin mà lỗi được tạo ra bằng phương pháp nào. Người ghi nhật ký lớp trong đoạn mã này thêm phần thông tin này vào một mục nhật ký mới.

https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts


-2

Nếu mã của bạn là JavaScript + PHP, thì số dòng PHP hiện tại có sẵn trong JavaScript dưới dạng hằng số theo nghĩa đen, vì nó có sẵn trong PHP dưới dạng   <?= __LINE__ ?>

(Đó là giả sử bạn đã bật các thẻ ngắn PHP.)

Vì vậy, ví dụ, trong JavaScript, bạn có thể nói:

this_php_line_number = <?= __LINE__ ?>;

Tuy nhiên, nếu bạn không cẩn thận, số dòng PHP có thể khác với số dòng JavaScript, vì PHP "ăn" các dòng nguồn trước khi trình duyệt nhìn thấy chúng. Vì vậy, vấn đề trở nên đảm bảo rằng số dòng PHP và JavaScript của bạn giống nhau. Nếu chúng khác nhau thì việc sử dụng trình gỡ lỗi JavaScript của trình duyệt sẽ kém thú vị hơn rất nhiều.

Bạn có thể đảm bảo số dòng giống nhau bằng cách bao gồm một câu lệnh PHP ghi đúng số dòng mới cần thiết để đồng bộ hóa số dòng phía máy chủ (PHP) và phía trình duyệt (JavaScript).

Đây là mã của tôi trông như thế nào:

<!DOCTYPE html>
<html lang="en">
<!-- Copyright 2016, 2017, me and my web site -->
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, user-scalable=yes">

<?php

...lots of PHP stuff here, including all PHP function definitions ...

echo str_repeat("\n",__LINE__-6); # Synchronize PHP and JavaScript line numbers
?>
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->

  <title>My web page title</title>

...lots of HTML and JavaScript stuff here...

</body>
</html>
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->

Chìa khóa là câu lệnh PHP này:

echo str_repeat("\n",__LINE__-6);

Điều đó tạo ra đủ dòng mới để làm cho số dòng mà JavaScript nhìn thấy giống với số dòng PHP. Tất cả các định nghĩa hàm PHP, v.v. đều ở trên cùng, trước dòng đó.

Sau dòng đó, tôi hạn chế sử dụng PHP đối với mã không thay đổi số dòng.

"-6" giải thích cho thực tế là mã PHP của tôi bắt đầu trên dòng 8. Nếu bạn bắt đầu mã PHP của mình sớm hơn, bạn sẽ giảm con số đó. Một số người đặt PHP của họ ở vị trí hàng đầu, thậm chí đi trước DOCTYPE.

(Dòng meta viewport tắt tính năng "tăng cường phông chữ" của Android Chrome theo Câu hỏi và đáp về Stack Overflow này: Chrome trên Android thay đổi kích thước phông chữ . Hãy xem xét đó là bản soạn sẵn, mà mọi trang web đều cần.)

Dòng sau chỉ để xác minh rằng tôi không mắc lỗi. Được xem trong trình gỡ lỗi của trình duyệt hoặc bằng cách nhấp chuột phải / lưu-trang web, nó sẽ trở thành một nhận xét HTML hiển thị đúng tên tệp nguồn và số dòng:

<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->

trở thành:

<!-- *** this is line 1234 of my_file.php *** -->

Bây giờ, bất cứ nơi nào tôi nhìn thấy một số dòng, cho dù nó nằm trong thông báo lỗi hay trong trình gỡ lỗi JavaScript, nó đều chính xác. Số dòng trong PHP và số dòng JavaScript luôn nhất quán và giống hệt nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.