JavaScript có cơ chế xác định số dòng của câu lệnh hiện đang thực thi không (và nếu có thì nó là gì)?
JavaScript có cơ chế xác định số dòng của câu lệnh hiện đang thực thi không (và nếu có thì nó là gì)?
Câu trả lời:
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.
lineNumber
tính không tồn tại trên các đối tượng lỗi. Cũng không stack
:-)
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];
}
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.
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;
}
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.onerror
không được xác định / xử lý trong WebKit hoặc Opera (lần cuối cùng tôi đã kiểm tra)
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.
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
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.