Wie finden Sie die Aufruferfunktion in JavaScript heraus?


866
function main()
{
   Hello();
}

function Hello()
{
  // How do you find out the caller function is 'main'?
}

Gibt es eine Möglichkeit, den Aufrufstapel herauszufinden?


63
Ich hoffe, dies soll Ihnen nur beim Debuggen helfen. Unterschiedliches Verhalten basierend auf dem Anrufer ist eine schlechte Idee.
ABl.

Wann wäre dies zum Debuggen nützlich?
Anderson Green

33
@AndersonGreen, wenn Sie beispielsweise eine Standardmethode zum Rendern von Vorlagen haben und sehen, dass diese zweimal aufgerufen wird. Anstatt 1000 LoC zu durchkämmen oder mühsam mit dem Debugger durchzugehen, können Sie nur sehen, was der Stapel zu der Zeit war.
Tkone

28
Um die Stapelverfolgung anzuzeigen, verwenden Sie console.trace () für Chrome.
Ich

5
Warum ist das eine schlechte Idee?
Jacob Schneider

Antworten:


995
function Hello()
{
    alert("caller is " + Hello.caller);
}

Beachten Sie, dass diese Funktion nicht-Standard , aus Function.caller:

Nicht standardisiert
Diese Funktion ist nicht standardisiert und befindet sich nicht auf einer Standardspur. Verwenden Sie es nicht auf Produktionsstandorten mit Blick auf das Web: Es funktioniert nicht für jeden Benutzer. Es kann auch große Inkompatibilitäten zwischen Implementierungen geben, und das Verhalten kann sich in Zukunft ändern.


Das Folgende ist die alte Antwort aus dem Jahr 2008, die im modernen Javascript nicht mehr unterstützt wird:

function Hello()
{
    alert("caller is " + arguments.callee.caller.toString());
}

254
arguments.callee.caller.nameerhält den Namen der Funktion.
Rocket Hazmat

137
"Auf die Eigenschaften" Aufrufer "," Angerufene "und" Argumente "kann möglicherweise nicht über Funktionen im strengen Modus oder auf die Argumente Objekte für Aufrufe zugegriffen werden" - sie sind in ES5 veraltet und werden im strengen Modus entfernt.
ThatGuy

12
Es funktioniert nur, wenn Sie nicht den strengen Modus verwenden. Das Entfernen 'use strict';könnte also helfen.
pvorb

23
argumentsAuf CAN kann innerhalb einer Funktion im strengen Modus zugegriffen werden. Es wäre dumm, dies zu verwerfen. nur nicht von function.arguments von außen. Wenn Sie ein benanntes Argument haben, verfolgt die Argumentform [i] keine Änderungen, die Sie an der benannten Version innerhalb der Funktion vorgenommen haben.
rvr_jon

41
Diese Methode ist veraltet, seit dieser Beitrag im Jahr 2011 aufgeführt wurde. Die bevorzugte Methode ist jetzt Function.caller (Stand 2015).
Greg

152

StackTrace

Sie können den gesamten Stack-Trace mit browserspezifischem Code finden. Das Gute ist, dass jemand es bereits geschafft hat ; Hier ist der Projektcode auf GitHub .

Aber nicht alle Nachrichten sind gut:

  1. Es ist sehr langsam, den Stack-Trace zu erhalten. Seien Sie also vorsichtig (lesen Sie dies für weitere Informationen).

  2. Sie müssen Funktionsnamen definieren, damit die Stapelverfolgung lesbar ist. Denn wenn Sie Code wie diesen haben:

    var Klass = function kls() {
       this.Hello = function() { alert(printStackTrace().join('\n\n')); };
    }
    new Klass().Hello();

    Google Chrome benachrichtigt Sie, ... kls.Hello ( ...aber die meisten Browser erwarten einen Funktionsnamen direkt nach dem Keyword functionund behandeln ihn als anonyme Funktion. Ein nicht einmal Chrome kann den KlassNamen verwenden, wenn Sie den Namen nicht angebenkls der Funktion .

    Übrigens können Sie die Option an die Funktion printStackTrace übergeben, {guess: true}aber ich habe dadurch keine wirkliche Verbesserung festgestellt .

  3. Nicht alle Browser geben Ihnen die gleichen Informationen. Das heißt, Parameter, Codespalte usw.


Name der Anruferfunktion

Übrigens, wenn Sie nur den Namen der Anruferfunktion (in den meisten Browsern, aber nicht im Internet Explorer) möchten, können Sie Folgendes verwenden:

arguments.callee.caller.name

Beachten Sie jedoch, dass dieser Name nach dem functionSchlüsselwort steht. Ich habe keine Möglichkeit gefunden (auch nicht bei Google Chrome), mehr zu erreichen, ohne den Code der gesamten Funktion zu erhalten.


Funktionscode des Anrufers

Und die restlichen besten Antworten zusammenfassen (von Pablo Cabrera, Nourdine und Greg Hewgill). Die einzige browserübergreifende und wirklich sichere Sache, die Sie verwenden können, ist:

arguments.callee.caller.toString();

Welches zeigt den Code der Anruferfunktion. Leider reicht mir das nicht aus, und deshalb gebe ich Ihnen Tipps für die StackTrace und die Aufruferfunktion Name (obwohl sie nicht browserübergreifend sind).


1
Vielleicht sollten Sie Function.callerper @ Gregs Antwort
Zach Lysobey

Function.callerfunktioniert jedoch nicht im strengen Modus.
Rickard Elimää

54

Ich weiß, dass Sie "in Javascript" erwähnt haben, aber wenn der Zweck das Debuggen ist, ist es meiner Meinung nach einfacher, nur die Entwicklertools Ihres Browsers zu verwenden. So sieht es in Chrome aus: Geben Sie hier die Bildbeschreibung ein Legen Sie einfach den Debugger dort ab, wo Sie den Stapel untersuchen möchten.


3
Dies ist eine alte Frage ... aber dies ist definitiv die modernste Methode, dies heute zu tun.
Markstewie

53

Um es noch einmal zusammenzufassen (und klarer zu machen) ...

dieser Code:

function Hello() {
    alert("caller is " + arguments.callee.caller.toString());
}

ist gleichbedeutend damit:

function Hello() {
    alert("caller is " + Hello.caller.toString());
}

Das erste Bit ist eindeutig portabler, da Sie den Namen der Funktion ändern können, beispielsweise von "Hallo" in "Ciao", und trotzdem das Ganze zum Laufen bringen können.

In letzterem Fall müssten Sie alle Vorkommen ändern, wenn Sie den Namen der aufgerufenen Funktion (Hallo) umgestalten möchten :(


7
Argumente.callee.caller immer null auf Chrome 25.0.1364.5 dev
Kokizzu

53

Sie können die vollständige Stapelverfolgung erhalten:

arguments.callee.caller
arguments.callee.caller.caller
arguments.callee.caller.caller.caller

Bis der Anrufer ist null.

Hinweis: Es verursacht eine Endlosschleife für rekursive Funktionen.


2
Entschuldigen Sie die späte Antwort, aber ich habe Ihren Kommentar noch nicht gesehen. Nur für den Rekursionsfall funktioniert es nicht, in anderen Fällen sollte es funktionieren.
Ale5000

45

Ich benutze normalerweise (new Error()).stack in Chrome. Das Schöne ist, dass Sie dadurch auch die Zeilennummern erhalten, unter denen der Anrufer die Funktion aufgerufen hat. Der Nachteil ist, dass es die Länge des Stapels auf 10 begrenzt, weshalb ich überhaupt auf diese Seite gekommen bin.

(Ich verwende dies, um Callstacks in einem Konstruktor auf niedriger Ebene während der Ausführung zu sammeln, um sie später anzuzeigen und zu debuggen. Das Festlegen eines Haltepunkts ist daher nicht hilfreich, da er tausende Male getroffen wird.)


Könnten Sie bitte etwas mehr Beschreibung zu der von Ihnen bereitgestellten Erklärung hinzufügen?
Abarisone

6
Dies ist das einzige, was ich zur Arbeit bringen könnte, wenn es vorhanden 'use strict';ist. Hat mir die Infos gegeben, die ich brauchte - danke!
Jeremy Harris

4
In Bezug auf die Begrenzung der Stapellänge ... können Sie dies mit "Error.stackTraceLimit = Infinity" ändern.
Tom

(neuer Fehler ("StackLog")). stack.split ("\ n") erleichtert das Lesen.
Teoman Shipahi


22

Sie können Function.Caller verwenden, um die aufrufende Funktion abzurufen. Die alte Methode mit argument.caller gilt als veraltet.

Der folgende Code veranschaulicht seine Verwendung:

function Hello() { return Hello.caller;}

Hello2 = function NamedFunc() { return NamedFunc.caller; };

function main()
{
   Hello();  //both return main()
   Hello2();
}

Hinweise zu veraltetem argument.caller: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller

Beachten Sie, dass Function.caller kein Standard ist: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller


1
Dies ist heutzutage die richtige Antwort. Sie können keine argument.caller.callee-Sachen mehr machen. Ich wünschte, wir könnten dies nach oben bringen, da alle anderen Sachen jetzt veraltet sind.
Coblr

4
Scheint, dass dies im strengen Modus nicht möglich ist? Cannot access caller property of a strict mode function
Zach Lysobey

Function.caller hat bei mir auch im strengen Modus nicht funktioniert. Auch nach MDN , function.caller ist Nicht-Standard und sollte nicht in der Produktion verwendet werden. Es könnte jedoch zum Debuggen funktionieren.
jkdev

Ich hatte kein Problem mit Nicht-Standard, wenn es in Node funktionierte, aber es ist einfach nicht im strengen Modus erlaubt (ich habe auf Node 6.10 getestet). Gleiches gilt für 'Argumente'. Ich erhalte die Fehlermeldung: '' 'Aufrufer' und 'Argumente' sind eingeschränkte Funktionseigenschaften und können in diesem Zusammenhang nicht aufgerufen werden. "
Tom

21

Ich würde das tun:

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

Das funktioniert super! sollte als die richtige Antwort akzeptiert werden, da andere Wege alt sind \ nicht mehr funktionieren
Yuval Pruss



16

Sieht so aus, als wäre dies eine ziemlich gelöste Frage, aber ich habe kürzlich herausgefunden, dass Angerufene im "strengen Modus" nicht erlaubt sind. Deshalb habe ich für meinen eigenen Gebrauch eine Klasse geschrieben, die den Pfad erhält, von dem aus sie aufgerufen wird. Es ist Teil einer kleinen Hilfsbibliothek. Wenn Sie den Code Standalone verwenden möchten, ändern Sie den Offset, der zum Zurückgeben der Stapelverfolgung des Aufrufers verwendet wird (verwenden Sie 1 anstelle von 2).

function ScriptPath() {
  var scriptPath = '';
  try {
    //Throw an error to generate a stack trace
    throw new Error();
  }
  catch(e) {
    //Split the stack trace into each line
    var stackLines = e.stack.split('\n');
    var callerIndex = 0;
    //Now walk though each line until we find a path reference
    for(var i in stackLines){
      if(!stackLines[i].match(/http[s]?:\/\//)) continue;
      //We skipped all the lines with out an http so we now have a script reference
      //This one is the class constructor, the next is the getScriptPath() call
      //The one after that is the user code requesting the path info (so offset by 2)
      callerIndex = Number(i) + 2;
      break;
    }
    //Now parse the string for each section we want to return
    pathParts = stackLines[callerIndex].match(/((http[s]?:\/\/.+\/)([^\/]+\.js)):/);
  }

  this.fullPath = function() {
    return pathParts[1];
  };

  this.path = function() {
    return pathParts[2];
  };

  this.file = function() {
    return pathParts[3];
  };

  this.fileNoExt = function() {
    var parts = this.file().split('.');
    parts.length = parts.length != 1 ? parts.length - 1 : 1;
    return parts.join('.');
  };
}

Funktioniert bei mir nicht mit function a(){ function b(){ function c(){ return ScriptPath(); } return c(); } return b(); } a()in der Konsole (habe es nicht in einer Datei versucht), scheint aber eine vernünftige Idee zu haben. Sollte aus Gründen der Sichtbarkeit ohnehin positiv bewertet werden.
Ninjagecko

Die Idee ist großartig. Ich analysiere anders, aber in nw.js Apps ist dies wirklich die einzige Idee, die das gibt, wonach ich suche.
Andrew Grothe

Bitte geben Sie ein Beispiel für den Aufruf dieser Funktion.
pd_au


11

Protokollieren Sie einfach Ihren Fehlerstapel auf der Konsole. Sie können dann wissen, wie Sie angerufen werden

const hello = () => {
  console.log(new Error('I was called').stack)
}

const sello = () => {
  hello()
}

sello()


10

Verwenden Sie sowohl im ES6- als auch im Strict-Modus Folgendes, um die Anruferfunktion zu erhalten

console.log((new Error()).stack.split("\n")[2].trim().split(" ")[1])

Bitte beachten Sie, dass die obige Zeile eine Ausnahme auslöst, wenn kein Aufrufer oder kein vorheriger Stapel vorhanden ist. Verwenden Sie entsprechend.


Um Angerufene (den aktuellen Funktionsnamen) zu erhalten, verwenden Sie: console.log((new Error()).stack.split("\n")[1].trim().split(" ")[1])
VanagaS

10

Update 2018

callerist im strengen Modus verboten . Hier ist eine Alternative mit dem (nicht standardmäßigen) ErrorStapel .

Die folgende Funktion scheint die Aufgabe in Firefox 52 und Chrome 61-71 zu erfüllen, obwohl ihre Implementierung viele Annahmen über das Protokollierungsformat der beiden Browser macht und mit Vorsicht verwendet werden sollte, da sie eine Ausnahme auslöst und möglicherweise zwei reguläre Ausdrücke ausführt Matchings bevor es fertig ist.

'use strict';
const fnNameMatcher = /([^(]+)@|at ([^(]+) \(/;

function fnName(str) {
  const regexResult = fnNameMatcher.exec(str);
  return regexResult[1] || regexResult[2];
}

function log(...messages) {
  const logLines = (new Error().stack).split('\n');
  const callerName = fnName(logLines[1]);

  if (callerName !== null) {
    if (callerName !== 'log') {
      console.log(callerName, 'called log with:', ...messages);
    } else {
      console.log(fnName(logLines[2]), 'called log with:', ...messages);
    }
  } else {
    console.log(...messages);
  }
}

function foo() {
  log('hi', 'there');
}

(function main() {
  foo();
}());


4
Das ist unglaublich und auch schrecklich.
Ian

Ich habe "foo angerufen mit: hi there", aber foo wurde nicht mit "hi there" aufgerufen , log wurde mit "hi there"
aufgerufen

Richtig, es gab einen "falsch platzierten Modifikator" in der Grammatik der Fehlermeldung. Es sollte heißen "Protokoll wurde von Funktion f aufgerufen, es wollte, dass die Nachricht X gedruckt wird", aber so kurz wie möglich.
Rovanion

7

Ich wollte hier meine Geige hinzufügen:

http://jsfiddle.net/bladnman/EhUm3/

Ich habe getestet, dass dies Chrom, Safari und IE (10 und 8) ist. Funktioniert gut. Es gibt nur eine Funktion, die wichtig ist. Wenn Sie also Angst vor der großen Geige haben, lesen Sie weiter unten.

Hinweis: In dieser Geige befindet sich eine ganze Menge meiner eigenen "Boilerplate". Sie können all das entfernen und Splits verwenden, wenn Sie möchten. Es ist nur ein ultra-sicherer Satz von Funktionen, auf die ich mich verlassen kann.

Es gibt dort auch eine "JSFiddle" -Vorlage, die ich für viele Geigen verwende, um einfach schnell zu fummeln.


Ich frage mich, ob Sie die "Helfer" in einigen Fällen als Erweiterungen für den Prototyp hinzufügen könnten, zum Beispiel:String.prototype.trim = trim;
autistisch

6

Wenn Sie nur den Funktionsnamen und nicht den Code und eine browserunabhängige Lösung wünschen, verwenden Sie Folgendes:

var callerFunction = arguments.callee.caller.toString().match(/function ([^\(]+)/)[1];

Beachten Sie, dass das oben Gesagte einen Fehler zurückgibt, wenn keine Aufruferfunktion vorhanden ist, da das Array kein [1] -Element enthält. Verwenden Sie zum Umgehen Folgendes:

var callerFunction = (arguments.callee.caller.toString().match(/function ([^\(]+)/) === null) ? 'Document Object Model': arguments.callee.caller.toString().match(/function ([^\(]+)/)[1], arguments.callee.toString().match(/function ([^\(]+)/)[1]);


5

Ich möchte Sie nur wissen lassen, dass auf PhoneGap / Android das nicht zu namefunktionieren scheint. Aber arguments.callee.caller.toString()wird den Trick machen.


4

Hier ist alles , aber das functionnameist gestrippt aus caller.toString(), mit RegExp.

<!DOCTYPE html>
<meta charset="UTF-8">
<title>Show the callers name</title><!-- This validates as html5! -->
<script>
main();
function main() { Hello(); }
function Hello(){
  var name = Hello.caller.toString().replace(/\s\([^#]+$|^[^\s]+\s/g,'');
  name = name.replace(/\s/g,'');
  if ( typeof window[name] !== 'function' )
    alert ("sorry, the type of "+name+" is "+ typeof window[name]);
  else
    alert ("The name of the "+typeof window[name]+" that called is "+name);
}
</script>

Dies gibt immer noch die gesamte Methodendeklaration zurück
Maslow


3

Die Antwort von heystewart und die Antwort von JiarongWu erwähnten beide, dass das ErrorObjekt Zugriff auf die hat stack.

Hier ist ein Beispiel:

function main() {
  Hello();
}

function Hello() {
  var stack;
  try {
    throw new Error();
  } catch (e) {
    stack = e.stack;
  }
  // N.B. stack === "Error\n  at Hello ...\n  at main ... \n...."
  var m = stack.match(/.*?Hello.*?\n(.*?)\n/);
  if (m) {
    var caller_name = m[1];
    console.log("Caller is:", caller_name)
  }
}

main();

Verschiedene Browser zeigen den Stapel in verschiedenen Zeichenfolgenformaten:

Safari : Caller is: main@https://stacksnippets.net/js:14:8 Firefox : Caller is: main@https://stacksnippets.net/js:14:3 Chrome : Caller is: at main (https://stacksnippets.net/js:14:3) IE Edge : Caller is: at main (https://stacksnippets.net/js:14:3) IE : Caller is: at main (https://stacksnippets.net/js:14:3)

Die meisten Browser setzen den Stack mit var stack = (new Error()).stack. In Internet Explorer ist der Stapel undefiniert - Sie müssen eine echte Ausnahme auslösen, um den Stapel abzurufen.

Fazit: Mit dem stackim ErrorObjekt kann festgestellt werden, dass "main" der Aufrufer von "Hello" ist . Tatsächlich funktioniert es in Fällen, in denen der callee/ caller-Ansatz nicht funktioniert. Es zeigt Ihnen auch den Kontext, dh die Quelldatei und die Zeilennummer. Es sind jedoch Anstrengungen erforderlich, um die Lösung plattformübergreifend zu gestalten.


2

Beachten Sie, dass Sie Function.caller in Node.js nicht verwenden können. Verwenden Sie stattdessen das Anrufer-ID- Paket. Zum Beispiel:

var callerId = require('caller-id');

function foo() {
    bar();
}
function bar() {
    var caller = callerId.getData();
    /*
    caller = {
        typeName: 'Object',
        functionName: 'foo',
        filePath: '/path/of/this/file.js',
        lineNumber: 5,
        topLevelFlag: true,
        nativeFlag: false,
        evalFlag: false
    }
    */
}

1

Versuchen Sie den folgenden Code:

function getStackTrace(){
  var f = arguments.callee;
  var ret = [];
  var item = {};
  var iter = 0;

  while ( f = f.caller ){
      // Initialize
    item = {
      name: f.name || null,
      args: [], // Empty array = no arguments passed
      callback: f
    };

      // Function arguments
    if ( f.arguments ){
      for ( iter = 0; iter<f.arguments.length; iter++ ){
        item.args[iter] = f.arguments[iter];
      }
    } else {
      item.args = null; // null = argument listing not supported
    }

    ret.push( item );
  }
  return ret;
}

Arbeitete für mich in Firefox-21 und Chrom-25.


Versuchen Sie dies für rekursive Funktionen.
Daniel1426

arguments.calleeist seit vielen Jahren veraltet .
Dan Dascalescu

1

Eine andere Möglichkeit, dieses Problem zu umgehen, besteht darin, einfach den Namen der aufrufenden Funktion als Parameter zu übergeben.

Zum Beispiel:

function reformatString(string, callerName) {

    if (callerName === "uid") {
        string = string.toUpperCase();
    }

    return string;
}

Jetzt können Sie die Funktion folgendermaßen aufrufen:

function uid(){
    var myString = "apples";

    reformatString(myString, function.name);
}

In meinem Beispiel wird eine fest codierte Überprüfung des Funktionsnamens verwendet, aber Sie können problemlos eine switch-Anweisung oder eine andere Logik verwenden, um dort das zu tun, was Sie möchten.


Ich glaube, dies löst zum größten Teil auch Probleme mit der Cross-Browser-Kompatibilität. Aber bitte testen Sie dies, bevor Sie davon ausgehen, dass es wahr ist! ( beginnt zu schwitzen )
GrayedFox

1

Soweit ich weiß, haben wir zwei Möglichkeiten dafür aus bestimmten Quellen wie diesen:

  1. Argumente.Caller

    function whoCalled()
    {
        if (arguments.caller == null)
           console.log('I was called from the global scope.');
        else
           console.log(arguments.caller + ' called me!');
    }
  2. Funktionsanrufer

    function myFunc()
    {
       if (myFunc.caller == null) {
          return 'The function was called from the top!';
       }
       else
       {
          return 'This function\'s caller was ' + myFunc.caller;
        }
    }

Denke du hast deine Antwort :).


Dies ist seit vielen Jahren veraltet und Function.caller funktioniert nicht im strengen Modus.
Dan Dascalescu

1

Warum alle oben genannten Lösungen wie eine Raketenwissenschaft aussehen. In der Zwischenzeit sollte es nicht komplizierter sein als dieses Snippet. Alle Credits an diesen Kerl

Wie finden Sie die Aufruferfunktion in JavaScript heraus?

var stackTrace = function() {

    var calls = [];
    var caller = arguments.callee.caller;

    for (var k = 0; k < 10; k++) {
        if (caller) {
            calls.push(caller);
            caller = caller.caller;
        }
    }

    return calls;
};

// when I call this inside specific method I see list of references to source method, obviously, I can add toString() to each call to see only function's content
// [function(), function(data), function(res), function(l), function(a, c), x(a, b, c, d), function(c, e)]

3
Dies ist, was ich damit benutze: TypeError: Auf die Eigenschaften 'caller', 'callee' und 'arguments' kann möglicherweise nicht über Funktionen des strengen Modus oder die Argumente-Objekte für Aufrufe an sie zugegriffen werden. Irgendwelche Ideen, wie man das im strengen Modus macht?
hard_working_ant

1

Ich versuche, mit dieser Frage sowohl die Frage als auch das aktuelle Kopfgeld anzusprechen.

Die Prämie erfordert, dass der Anrufer im strengen Modus erhalten wird, und die einzige Möglichkeit, dies zu sehen, besteht darin, auf eine außerhalb deklarierte Funktion zu verweisen des strengen Modus .

Das Folgende ist beispielsweise nicht Standard, wurde jedoch mit früheren (29.03.2016) und aktuellen (1. August 2018) Versionen von Chrome, Edge und Firefox getestet.

function caller()
{
   return caller.caller.caller;
}

'use strict';
function main()
{
   // Original question:
   Hello();
   // Bounty question:
   (function() { console.log('Anonymous function called by ' + caller().name); })();
}

function Hello()
{
   // How do you find out the caller function is 'main'?
   console.log('Hello called by ' + caller().name);
}

main();



0

Wenn Sie die Funktionalität aus irgendeinem Grund wirklich benötigen und möchten, dass sie browserübergreifend kompatibel ist und sich nicht um strenge Dinge kümmert und vorwärtskompatibel ist, übergeben Sie diese Referenz:

function main()
{
   Hello(this);
}

function Hello(caller)
{
    // caller will be the object that called Hello. boom like that... 
    // you can add an undefined check code if the function Hello 
    // will be called without parameters from somewhere else
}

0

Ich denke, das folgende Code-Stück kann hilfreich sein:

window.fnPureLog = function(sStatement, anyVariable) {
    if (arguments.length < 1) { 
        throw new Error('Arguments sStatement and anyVariable are expected'); 
    }
    if (typeof sStatement !== 'string') { 
        throw new Error('The type of sStatement is not match, please use string');
    }
    var oCallStackTrack = new Error();
    console.log(oCallStackTrack.stack.replace('Error', 'Call Stack:'), '\n' + sStatement + ':', anyVariable);
}

Führen Sie den Code aus:

window.fnPureLog = function(sStatement, anyVariable) {
    if (arguments.length < 1) { 
        throw new Error('Arguments sStatement and anyVariable are expected'); 
    }
    if (typeof sStatement !== 'string') { 
        throw new Error('The type of sStatement is not match, please use string');
    }
    var oCallStackTrack = new Error();
    console.log(oCallStackTrack.stack.replace('Error', 'Call Stack:'), '\n' + sStatement + ':', anyVariable);
}

function fnBsnCallStack1() {
    fnPureLog('Stock Count', 100)
}

function fnBsnCallStack2() {
    fnBsnCallStack1()
}

fnBsnCallStack2();

Das Protokoll sieht folgendermaßen aus:

Call Stack:
    at window.fnPureLog (<anonymous>:8:27)
    at fnBsnCallStack1 (<anonymous>:13:5)
    at fnBsnCallStack2 (<anonymous>:17:5)
    at <anonymous>:20:1 
Stock Count: 100
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.