วิธีรับหมายเลขบรรทัดฟังก์ชันผู้โทร JavaScript จะรับ URL ต้นทางของผู้โทร JavaScript ได้อย่างไร


109

ฉันใช้สิ่งต่อไปนี้เพื่อรับชื่อฟังก์ชันผู้โทร JavaScript:

var callerFunc = arguments.callee.caller.toString();
callerFuncName = (callerFunc.substring(callerFunc.indexOf("function") + 8, callerFunc.indexOf("(")) || "anoynmous")

มีวิธีค้นหาหมายเลขบรรทัดที่เรียกวิธีการนี้หรือไม่?

นอกจากนี้ยังมีวิธีรับชื่อไฟล์ JavaScript ที่เมธอดเรียกใช้หรือไม่? หรือ URL ต้นทาง?


2
ฉันไม่คิดว่าจะเป็นไปได้ใน IE หรือมิฉะนั้นเราจะมีวิธีแก้ไขข้อความแสดงข้อผิดพลาด CRAPPY ที่ไม่ให้รายละเอียด แต่ถ้าเป็นไปได้ฉันก็อยากจะรู้เช่นกัน!
Zoidberg

ใช่. นี่คือการทำงานของเบราว์เซอร์ที่ทำให้การใช้วิธีการที่เป็นกรรมสิทธิ์ของแต่ละเบราว์เซอร์: github.com/eriwen/javascript-stacktrace [ลิงค์ถาวร]
สกอตส์

คำตอบ:


99

สิ่งนี้ใช้ได้กับฉันใน chrome / QtWebView

function getErrorObject(){
    try { throw Error('') } catch(err) { return err; }
}

var err = getErrorObject();
var caller_line = err.stack.split("\n")[4];
var index = caller_line.indexOf("at ");
var clean = caller_line.slice(index+2, caller_line.length);

ทำงานในโหนดด้วย ใส่สิ่งนี้ไว้ในฟังก์ชัน log () ที่กำหนดเองของคุณ (ซึ่งจะเพิ่มวิธีแก้ปัญหาที่เป็นประโยชน์อื่น ๆ ที่คุณต้องการเช่นแก้ไขสำหรับการบันทึกอาร์เรย์ Chrome) และยังคงหมายเลขบรรทัดจากที่ใดก็ตามที่คุณเรียกว่า log ()
mikemaccana

60
ไม่จำเป็นต้องโยนข้อผิดพลาด แค่สร้างมันก็เพียงพอแล้ว:var caller_line = (new Error).stack.split("\n")[4]
ELLIOTTCABLE

2
รวมคำแนะนำนี้กับคำตอบอื่นที่คล้ายกันเพื่อให้ได้การตอบสนอง "มาตรฐาน" ของ FF / Webkit - ดูที่stackoverflow.com/a/14841411/1037948
drzaus

1
ทำงานใน PhantomJS ได้เช่นกัน แต่คุณต้องโยนทิ้งไม่เช่นนั้นแอตทริบิวต์ "stack" ไม่ได้ตั้งค่าไว้ในข้อผิดพลาด
Joshua Richardson

1
@ELLIOTTCABLE ที่เกิดขึ้นจริงในบางเบราว์เซอร์เช่น iOS Safari คุณจำเป็นต้องทิ้งข้อยกเว้น! แล้วทำไมไม่ทำล่ะ?
arctelix

26

โซลูชันของ kangax แนะนำขอบเขตการจับลองที่ไม่จำเป็น หากคุณจำเป็นต้องเข้าถึงจำนวนบรรทัดของบางสิ่งบางอย่างใน JavaScript (ตราบเท่าที่คุณใช้ Firefox หรือ Opera), (new Error).lineNumberเครื่องเพียง


11
สวัสดีขอบคุณสำหรับ addon นั้น คุณรู้หรือไม่ว่าเป็นไปได้ที่จะได้รับหมายเลขสายจากการโทรครั้งก่อน? ให้บอกว่าวิธีการ A โทร B และตอนนี้ใน BI อยากทราบว่าสายใต้สาย A ทำอะไร?

85
นี้เป็น ticked แต่ไม่ได้ตอบคำถามซึ่งเป็นวิธีการที่จะได้รับหมายเลขบรรทัดของฟังก์ชั่นโทร
mikemaccana

3
นอกจากนี้ยังมีข้อ จำกัด อย่างมาก ทางออกที่ดีที่สุดคือโยนข้อผิดพลาดและใช้ regex กับ error.stack ซึ่งมีอยู่ในเบราว์เซอร์สมัยใหม่ทั้งหมด คุณสามารถแยกเส้นทางไฟล์บรรทัดและคอลัมน์นั้นได้อย่างง่ายดาย ไม่มีปัญหา.
arctelix

13

ฉันประหลาดใจที่คำตอบเหล่านี้ส่วนใหญ่สันนิษฐานว่าคุณต้องการจัดการข้อผิดพลาดแทนที่จะส่งออกเพียงแค่การติดตามการดีบักที่เป็นประโยชน์สำหรับกรณีปกติเช่นกัน

ตัวอย่างเช่นฉันชอบใช้console.logกระดาษห่อหุ้มแบบนี้:

consoleLog = function(msg) {//See https://stackoverflow.com/a/27074218/470749
    var e = new Error();
    if (!e.stack)
        try {
            // IE requires the Error to actually be thrown 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/);
    if (msg === '') {
        msg = '""';
    }
    console.log(msg, '          [' + stack[1] + ']');        
}

สิ่งนี้จะจบลงด้วยการพิมพ์เอาต์พุตดังต่อไปนี้ไปยังคอนโซลของฉัน:

1462567104174 [getAllPosts@http://me.com/helper.js:362:9]

ดูhttps://stackoverflow.com/a/27074218/และยังมี Wrapper ที่เหมาะสมสำหรับ console.log ด้วยหมายเลขบรรทัดที่ถูกต้อง?


1
ใช้งานได้กับเบราว์เซอร์ firefox แต่ใช้กับ node.js ไม่ได้
ซิป

1
ภายใต้โหนดคุณต้องล็อกสแต็ก [2]
monika mevenkamp

5

สิ่งนี้มักทำได้โดยการโยนข้อผิดพลาดจากบริบทปัจจุบัน จากนั้นวิเคราะห์วัตถุข้อผิดพลาดสำหรับคุณสมบัติเช่นlineNumberและfileName(ซึ่งบางเบราว์เซอร์มี)

function getErrorObject(){
  try { throw Error('') } catch(err) { return err; }
}

var err = getErrorObject();

err.fileName;
err.lineNumber; // or `err.line` in WebKit

อย่าลืมว่าcallee.callerคุณสมบัตินั้นเลิกใช้งานแล้ว (และไม่เคยอยู่ใน ECMA 3rd ed. ตั้งแต่แรก)

โปรดจำไว้ว่าการแยกฟังก์ชันถูกระบุให้ขึ้นอยู่กับการนำไปใช้งานและอาจให้ผลลัพธ์ที่ไม่คาดคิด ผมเขียนเกี่ยวกับเรื่องนี้ที่นี่และที่นี่


ขอบคุณดูเหมือนว่าจะมีปัญหาเล็กน้อยในการเพิ่มรหัสนี้ในแอปพลิเคชันที่ฉันต้องการ (js tracing framework) คุณรู้วิธีการอื่นที่ฉันสามารถใช้ได้หรือไม่?
Tal

callee.callerคุณควรจะสามารถที่จะตรวจสอบวัตถุข้อผิดพลาดโดยไม่ต้องพึ่งเลิก
kangax

คุณไม่จำเป็นต้องโยน Error คุณเพียงแค่ใช้ (ข้อผิดพลาดใหม่) .lineNumber เพื่อเข้าถึงหมายเลขบรรทัดปัจจุบันในสคริปต์
Eli Gray

@Elijah นั่นคือสิ่งที่ฉันเห็นใน FF3 ในทางกลับกัน WebKit จะเติมข้อมูลlineเมื่อเกิดข้อผิดพลาดเท่านั้น
kangax

สิ่งที่ทดแทนสำหรับ callee.caller คืออะไร? ถ้าฉันต้องการชื่อฟังก์ชัน?

4

ดูเหมือนว่าฉันจะสายไปแล้ว :) แต่การสนทนานั้นน่าสนใจทีเดียว .. ต่อไปนี้ ... สมมติว่าคุณต้องการสร้างตัวจัดการข้อผิดพลาดและคุณกำลังใช้คลาสตัวจัดการข้อยกเว้นของคุณเองเช่น:

function  errorHandler(error){
    this.errorMessage = error;
}
errorHandler.prototype. displayErrors = function(){
    throw new Error(this.errorMessage);
}

และคุณกำลังห่อรหัสของคุณดังนี้:

try{
if(condition){
    //whatever...
}else{
    throw new errorHandler('Some Error Message');
}
}catch(e){
    e.displayErrors();
}

ส่วนใหญ่คุณจะมีตัวจัดการข้อผิดพลาดในไฟล์. js แยกต่างหาก

คุณจะสังเกตเห็นว่าในคอนโซลข้อผิดพลาดของ firefox หรือ chrome หมายเลขบรรทัดรหัส (และชื่อไฟล์) ที่แสดงคือบรรทัด (ไฟล์) ที่แสดงข้อยกเว้น "ข้อผิดพลาด" และไม่ใช่ข้อยกเว้น "errorHandler" ที่คุณต้องการจริงๆเพื่อทำการดีบัก ง่าย. การทิ้งข้อยกเว้นของคุณเองเป็นเรื่องดี แต่สำหรับโครงการขนาดใหญ่ที่พบข้อยกเว้นเหล่านี้อาจเป็นปัญหาได้โดยเฉพาะอย่างยิ่งหากมีข้อความที่คล้ายกัน ดังนั้นสิ่งที่คุณทำได้คือส่งการอ้างอิงไปยังวัตถุข้อผิดพลาดจริงที่ว่างเปล่าไปยังตัวจัดการข้อผิดพลาดของคุณและการอ้างอิงนั้นจะเก็บข้อมูลทั้งหมดที่คุณต้องการ (ตัวอย่างเช่นใน firefox คุณจะได้รับชื่อไฟล์และหมายเลขบรรทัดเป็นต้น ใน chrome คุณจะได้รับสิ่งที่คล้ายกันหากคุณอ่านคุณสมบัติ 'stack' ของอินสแตนซ์ Error) เรื่องสั้นสั้นคุณสามารถทำสิ่งนี้:

function  errorHandler(error, errorInstance){
    this.errorMessage = error;
    this. errorInstance = errorInstance;
}
errorHandler.prototype. displayErrors = function(){
    //add the empty error trace to your message
    this.errorMessage += '  stack trace: '+ this. errorInstance.stack;
    throw new Error(this.errorMessage);
}

try{
if(condition){
    //whatever...
}else{
    throw new errorHandler('Some Error Message', new Error());
}
}catch(e){
    e.displayErrors();
}

ตอนนี้คุณสามารถรับไฟล์และหมายเลขบรรทัดจริงที่ทำให้คุณได้รับข้อยกเว้นที่กำหนดเอง


4

จริงๆแล้วหมายเลขบรรทัดเป็นสิ่งที่คงที่ดังนั้นหากคุณต้องการเพียงแค่การบันทึกก็สามารถประมวลผลล่วงหน้าได้ด้วยบางอย่างเช่นอึก ฉันได้เขียนปลั๊กอินอึกเล็ก ๆที่ทำเช่นนั้น:

var gulp = require('gulp');
var logLine = require('gulp-log-line');
gulp.task('log-line', function() {
    return gulp.src("file.js", {buffer : true})
    //Write here the loggers you use.
        .pipe(logLine(['console.log']))
        .pipe(gulp.dest('./build'))

})

gulp.task('default', ['log-line'])

นี้จะแนบชื่อไฟล์และสายที่จะบันทึกทั้งหมดออกจาก console.log ดังนั้นจะกลายเป็นconsole.log(something) console.log('filePath:fileNumber', something)ข้อดีคือตอนนี้คุณสามารถเชื่อมต่อไฟล์ของคุณถ่ายโอน ... และคุณจะยังคงได้รับบรรทัด


นี่เป็นคำแนะนำที่ดีสำหรับสถานการณ์ที่ใช้ทรานสไพเลอร์ (เช่นเมื่อใช้ TypeScript) ขอบคุณ!
Andy King

4

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ตอนนี้มีวิธีที่เรียกว่า console.trace("Message")ว่าจะแสดงหมายเลขบรรทัดและสายวิธีการโทรที่นำไปสู่บันทึกพร้อมกับข้อความที่คุณส่งผ่าน ดูข้อมูลเพิ่มเติมเกี่ยวกับเทคนิคการบันทึกจาวาสคริปต์ได้ที่ freecodecampและโพสต์บล็อกขนาดกลางนี้


3

หากคุณต้องการทราบหมายเลขบรรทัดเพื่อจุดประสงค์ในการดีบักหรือเฉพาะในระหว่างการพัฒนา (ด้วยเหตุผลหรืออย่างอื่น) คุณสามารถใช้Firebug (ส่วนขยายของ Firefox) และทิ้งข้อยกเว้น

แก้ไข :

หากคุณจำเป็นต้องทำเช่นนั้นในการผลิตด้วยเหตุผลบางประการคุณสามารถประมวลผลไฟล์จาวาสคริปต์ของคุณล่วงหน้าเพื่อให้แต่ละฟังก์ชั่นติดตามรายการที่เปิดอยู่ ฉันรู้ว่ากรอบงานบางส่วนที่พบความครอบคลุมของโค้ดใช้สิ่งนี้ (เช่นJSCoverage )

ตัวอย่างเช่นสมมติว่าการโทรเดิมของคุณคือ:

function x() {
  1 + 1;
  2 + 2;
  y();
}

คุณสามารถเขียนพรีโปรเซสเซอร์เพื่อสร้างเป็น:

function x() {
  var me = arguments.callee;
  me.line = 1;
  1 + 1;
  me.line = 2;
  2 + 2;
  me.line = 3;
  y();
}

จากนั้นy()คุณสามารถใช้arguments.callee.caller.lineเพื่อทราบบรรทัดที่เรียกได้เช่น:

function y() {
  alert(arguments.callee.caller.line);
}

1
ขอบคุณฉันต้องการสิ่งนี้ในการผลิตเพื่อเหตุผลสนับสนุน ฉันพบรหัสบางอย่างที่ช่วยให้คุณเห็น call stack ของโฟลว์ทั้งหมดจนถึงเมธอด แต่ไม่มีหมายเลขบรรทัดที่เรียกเมธอด ฉันเดาว่าจะแก้ปัญหาได้ง่ายหรือไม่
Tal

3

นี่คือวิธีที่ฉันได้ทำไปแล้วฉันได้ทดสอบทั้งใน Firefox และ Chrome ทำให้สามารถตรวจสอบชื่อไฟล์และหมายเลขบรรทัดของตำแหน่งที่เรียกใช้ฟังก์ชันได้

logFileAndLineNumber(new Error());

function logFileAndLineNumber(newErr)
{
   if(navigator.userAgent.indexOf("Firefox") != -1)
   {
      var originPath = newErr.stack.split('\n')[0].split("/");
      var fileNameAndLineNumber = originPath[originPath.length - 1].split(">")[0];
      console.log(fileNameAndLineNumber);
   }else if(navigator.userAgent.indexOf("Chrome") != -1)
   {
      var originFile = newErr.stack.split('\n')[1].split('/');
      var fileName = originFile[originFile.length - 1].split(':')[0];
      var lineNumber = originFile[originFile.length - 1].split(':')[1];
      console.log(fileName+" line "+lineNumber);
    }
}

2

นี่คือสิ่งที่ฉันเขียนตามข้อมูลที่พบในฟอรัมนี้:

นี่เป็นส่วนหนึ่งของ MyDebugNamespace เห็นได้ชัดว่า Debug ถูกสงวนไว้และจะไม่ทำเป็นชื่อเนมสเปซ

    var DEBUG = true;

...

    if (true == DEBUG && !test)
    {
        var sAlert = "Assertion failed! ";
        if (null != message)
            sAlert += "\n" + message;
        if (null != err)
            sAlert += "\n" + "File: " + err.fileName + "\n" + "Line: " + err.lineNumber;
        alert(sAlert);
    }

...

วิธีโทร:

    MyDebugNamespace.Assert(new Error(""), (null != someVar), "Something is wrong!")

ฉันรวมฟังก์ชันสองฟังก์ชันพร้อมกับจำนวนอาร์กิวเมนต์ที่เรียกรหัสฐานนี้ในเนมสเปซของฉันเพื่อที่จะไม่เลือกข้อความหรือข้อผิดพลาดในการโทร

วิธีนี้ใช้ได้ดีกับ Firefox, IE6 และ Chrome รายงาน fileName และ lineNumber ตามที่ไม่ได้กำหนด


2

รหัสต่อไปนี้ใช้ได้กับฉันใน Mozilla และ Chrome

ฟังก์ชันบันทึกที่แสดงชื่อไฟล์และบรรทัดของผู้โทร

log: function (arg) {
    var toPrint = [];
    for (var i = 0; i < arguments.length; ++i) {
        toPrint.push(arguments[i]);
    }

    function getErrorObject(){
        try { throw Error('') } catch(err) { return err; }
    }

    var err = getErrorObject(),
        caller;

    if ($.browser.mozilla) {
        caller = err.stack.split("\n")[2];
    } else {
        caller = err.stack.split("\n")[4];
    }

    var index = caller.indexOf('.js');

    var str = caller.substr(0, index + 3);
    index = str.lastIndexOf('/');
    str = str.substr(index + 1, str.length);

    var info = "\t\tFile: " + str;

    if ($.browser.mozilla) {
        str = caller;
    } else {
        index = caller.lastIndexOf(':');
        str = caller.substr(0, index);
    }
    index = str.lastIndexOf(':');
    str = str.substr(index + 1, str.length);
    info += " Line: " + str;
    toPrint.push(info);

    console.log.apply(console, toPrint);
}

ดูเหมือนมีบางอย่างหายไป ฉันได้รับ:SyntaxError: function statement requires a name,log: function (arg) {
spiderplant0

ฉันชอบแนวคิดนี้ แต่หมายเลขบรรทัดออกมาไม่ถูกต้องสำหรับฉัน
Ryan

2

การมีส่วนร่วมของฉันต่อข้อผิดพลาดที่กำหนดเองใน JavaScript:

  1. ก่อนอื่นฉันเห็นด้วยกับผู้ชาย @BT คนนี้ที่รับมรดกจากวัตถุข้อผิดพลาด - คุณสมบัติของข้อความอยู่ที่ไหน เราต้องสร้างให้ถูกต้อง (จริงๆแล้วคุณต้องใช้ไลบรารีวัตถุ js สิ่งที่ฉันชอบ: https://github.com/jiem/my-class ):

    window.g3 = window.g3 || {};
    g3.Error = function (message, name, original) {
         this.original = original;
         this.name = name || 'Error.g3';
         this.message = message || 'A g3.Error was thrown!';
         (original)? this.stack = this.original.stack: this.stack = null;
         this.message += '<br>---STACK---<br>' + this.stack;
     };
    
     var ClassEmpty = function() {};
     ClassEmpty.prototype = Error.prototype;
     g3.Error.prototype = new ClassEmpty();
     g3.Error.prototype.constructor = g3.Error;
  2. จากนั้นเราควรกำหนดฟังก์ชันการจัดการข้อผิดพลาดทั่วโลก (ทางเลือก) มิฉะนั้นจะจบลงที่เครื่องยนต์:

    window.onerror = printError; 
    function printError(msg, url, line){
        document.getElementById('test').innerHTML = msg+'<br>at: '+url+'<br>line: '+line;
        return true;
    }
  3. สุดท้ายเราควรโยนข้อผิดพลาดที่กำหนดเองอย่างระมัดระวัง:

    //hit it!
    //throw new g3.Error('Hey, this is an error message!', 'Error.Factory.g3');
    throw new g3.Error('Hey, this is an error message!', 'Error.Factory.g3', new Error());

เฉพาะเมื่อส่งผ่านพารามิเตอร์ที่สามเป็น new Error()เราจะเห็นสแต็กพร้อมฟังก์ชันและหมายเลขบรรทัดเท่านั้น!

ที่ 2 ฟังก์ชั่นนี้สามารถจัดการข้อผิดพลาดที่เกิดจากเครื่องยนต์ได้เช่นกัน

แน่นอนว่าคำถามที่แท้จริงคือเราต้องการมันจริงๆหรือไม่และเมื่อไร มีหลายกรณี (99% ในความคิดของฉัน) ที่การกลับมาอย่างสง่างามfalseนั้นเพียงพอและเหลือเพียงจุดวิกฤตบางจุดที่จะแสดงให้เห็นพร้อมกับข้อผิดพลาดที่เกิดขึ้น

ตัวอย่าง: http://jsfiddle.net/centurianii/m2sQ3/1/



1

ในการพิจารณาว่าบรรทัดใดอยู่ในรายการคุณต้องค้นหารหัสทั้งหมดสำหรับรหัสที่ตรงกับบรรทัดที่สนใจและนับอักขระ "\ n" จากด้านบนสุดจนถึงส่วนที่สนใจและเพิ่ม 1

ฉันกำลังทำสิ่งนี้ในแอปพลิเคชันที่ฉันกำลังเขียนอยู่ เป็นเครื่องมือตรวจสอบแนวทางปฏิบัติที่ดีที่สุดสำหรับ HTML และยังอยู่ระหว่างการพัฒนาอย่างหนัก แต่กระบวนการแสดงข้อผิดพลาดที่คุณสนใจจะเสร็จสมบูรณ์

http://mailmarkup.org/htmlint/htmlint.html


บรรทัดที่สนใจอาจมีได้หลายแบบ ... ถ้าฉันมีวิธีเดียวกันที่เรียกหลาย ๆ ครั้งจากวิธีอื่นฉันจะรู้ได้อย่างไรว่า (ในวิธีอื่นนั้น) สายมาจากไหน?
Tal

คุณจะไม่สามารถวิเคราะห์การตีความ JavaScript ในเวลาดำเนินการจากภายนอกล่ามได้ คุณสามารถเขียนโปรแกรมเพื่อติดตามเส้นทางการดำเนินการในโปรแกรมของคุณได้ แต่จะเป็นโปรแกรมที่กำลังดำเนินการไม่ใช่โค้ดที่คุณต้องการวิเคราะห์ โดยทั่วไปเป็นงานที่ซับซ้อนซึ่งดำเนินการด้วยตนเองโดยใช้เครื่องมือ หากคุณต้องการเห็นสิ่งที่เกิดขึ้นในโค้ดของคุณในขณะที่รันอยู่ให้เขียนข้อมูลเมตาลงบนหน้าจอเพื่อบอกว่าคุณต้องการให้การตัดสินใจดำเนินการในส่วนใด

-2

คำตอบนั้นง่ายมาก ไม่ใช่และไม่ใช่ (ไม่ใช่)

เมื่อถึงเวลาที่จาวาสคริปต์กำลังเรียกใช้แนวคิดของไฟล์ต้นฉบับ / URL ที่มานั้นหายไป

นอกจากนี้ยังไม่มีวิธีในการกำหนดหมายเลขบรรทัดเนื่องจากอีกครั้งเมื่อถึงเวลาดำเนินการแนวคิดของรหัส "เส้น" จะไม่มีความหมายใน Javascript อีกต่อไป

การใช้งานเฉพาะอาจจัดเตรียม API hooks เพื่อให้สามารถเข้าถึงรหัสส่วนตัวเพื่อเข้าถึงรายละเอียดดังกล่าวเพื่อจุดประสงค์ในการดีบัก แต่ API เหล่านี้จะไม่เปิดเผยกับโค้ด Javascript มาตรฐานทั่วไป


ใน firefox ข้อยกเว้นรวมถึงข้อมูลดังกล่าว ... เป็นไปได้อย่างน้อยใน firefox?
Zoidberg

เมื่อคุณเปิดตัวดีบักเกอร์ MS Script และวางเบรกพอยต์คุณจะเห็นใน call stack ว่าคุณมาจากไหน นี่เป็นเพราะตะขอเฉพาะ?
Tal

"อีกครั้งในช่วงเวลาของการดำเนินการแนวคิดของรหัส" บรรทัด "ไม่มีความหมายใน Javascript อีกต่อไป" ฮะ? JS แสดงหมายเลขบรรทัดทุกครั้งที่คุณเรียกใช้ console.log () อยู่แล้ว
mikemaccana

@AnthonyWJones ใช่ มันขัดแย้งกับคำว่า 'No and No (No)' อย่างสิ้นเชิง
mikemaccana

@nailer: ย้อนกลับไปในปี 2009 ในเบราว์เซอร์หลัก ๆ ทั้งหมดคำตอบของฉันขัดแย้งในทางใด จำไว้ว่าคำถามในมือคือการค้นพบในการเรียกใช้จาวาสคริปต์ของหมายเลขบรรทัดของ callee หรือไม่?
AnthonyWJones
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.