ජාවාස්ක්‍රිප්ට් හි ඇමතුම් ශ්‍රිතය ඔබ සොයා ගන්නේ කෙසේද?


882
function main()
{
   Hello();
}

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

ඇමතුම් තොගය සොයා ගැනීමට ක්‍රමයක් තිබේද?


65
මෙය නිදොස් කිරීම සඳහා ඔබට සහාය වනු ඇතැයි මම බලාපොරොත්තු වෙමි. අමතන්නා මත පදනම්ව හැසිරීම වෙනස් කිරීම නරක අදහසකි.
ඕ.ජේ.

නිදොස්කරණය සඳහා මෙය ප්‍රයෝජනවත් වන්නේ කවදාද?
ඇන්ඩර්සන් ග්‍රීන්

34
Nd ඇන්ඩර්සන් ග්‍රීන් ඔබ සතුව ඇති විට, පෙරනිමි අච්චු විදැහුම් ක්‍රමයක් ඇති අතර එය දෙවරක් කැඳවනු ලැබේ. සීමාසහිත 1000 ක් හරහා හෝ නිදොස් කිරීම සමඟ වෙහෙස මහන්සි වී වැඩ කරනවා වෙනුවට, ඔබට එකල තොගය කුමක්දැයි දැක ගත හැකිය.
tkone

28
තොග හෝඩුවාව බැලීමට chrome සඳහා console.trace () භාවිතා කරන්න. අනෙක් අය ගැන දන්නේ නැත
lukas.pukenis

6
මෙය නරක අදහසක් වන්නේ ඇයි?
ජේකබ් ෂ්නයිඩර්

Answers:


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

මෙම අංගය සම්මත නොවන බව සලකන්න , සිට Function.caller:

සම්මත නොවන
මෙම අංගය සම්මත නොවන අතර එය ප්‍රමිති ධාවන පථයක නොමැත. වෙබයට මුහුණ ලා සිටින නිෂ්පාදන අඩවි වල එය භාවිතා නොකරන්න: එය සෑම පරිශීලකයෙකුටම ක්‍රියා නොකරනු ඇත. ක්‍රියාත්මක කිරීම අතර විශාල නොගැලපීම් ද තිබිය හැකි අතර අනාගතයේ දී හැසිරීම වෙනස් විය හැකිය.


නූතන ජාවාස්ක්‍රිප්ට් හි තවදුරටත් සහාය නොදක්වන 2008 සිට පැරණි පිළිතුර පහත දැක්වේ.

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

255
arguments.callee.caller.nameශ්‍රිතයේ නම ලැබෙනු ඇත.
රොකට් හස්මාත්

138
"'අමතන්නා', 'ඇමතුම්' සහ 'තර්ක' ගුණාංග දැඩි මාදිලියේ ක්‍රියාකාරිත්වයන් හෝ ඒවාට ඇමතුම් සඳහා වන තර්ක වස්තු වෙත ප්‍රවේශ නොවිය හැකිය" - ඒවා ES5 වලින් ඉවත් කර දැඩි ආකාරයෙන් ඉවත් කරනු ලැබේ.
ThatGuy

14
එය ක්‍රියාත්මක වන්නේ ඔබ දැඩි මාදිලියක් භාවිතා නොකරන්නේ නම් පමණි. එබැවින් ඉවත් කිරීම 'use strict';උපකාරී වේ.
pvorb

23
argumentsදැඩි මාදිලියකින් ශ්‍රිතයක් තුළට පිවිසිය හැකිය, එය අවලංගු කිරීම මෝඩකමකි. function.arguments පිටතින් නොවේ. එසේම, ඔබට නම් කරන ලද තර්කයක් තිබේ නම්, එහි තර්ක [i] ආකෘතිය මඟින් ශ්‍රිතය තුළ නම් කරන ලද අනුවාදයට ඔබ සිදුකරන වෙනස්කම් නිරීක්ෂණය නොකෙරේ.
rvr_jon

41
මෙම තනතුර 2011 දී ලැයිස්තුගත කර ඇති බැවින් මෙම ක්‍රමය යල් පැන ගොස් ඇත. වඩාත් කැමති ක්‍රමය දැන් Function.caller වේ (2015 වන විට).
ග්‍රෙග්

154

ස්ටැක්ට්‍රේස්

බ්‍රව්සරයේ විශේෂිත කේතය භාවිතයෙන් ඔබට සම්පූර්ණ තොග හෝඩුවාව සොයාගත හැකිය. හොඳ දෙය නම් යමෙකු දැනටමත් එය සාදා ඇත ; GitHub හි ව්‍යාපෘති කේතය මෙන්න .

නමුත් සියලු ප්‍රවෘත්ති හොඳ නැත:

  1. තොග හෝඩුවාව ලබා ගැනීම සැබවින්ම මන්දගාමී බැවින් ප්‍රවේශම් වන්න ( වැඩි විස්තර සඳහා මෙය කියවන්න ).

  2. තොග හෝඩුවාව පැහැදිලිව පෙනෙන පරිදි ඔබට ක්‍රියාකාරී නම් නිර්වචනය කිරීමට අවශ්‍ය වනු ඇත. මන්ද ඔබට මේ වගේ කේතයක් තිබේ නම්:

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

    ගූගල් ක්‍රෝම් අනතුරු ඇඟවීමක් කරනු ඇති ... kls.Hello ( ...නමුත් බොහෝ බ්‍රව්සර් යතුරුපදයට පසුව ක්‍රියාකාරී නාමයක් අපේක්ෂා කරන අතර functionඑය නිර්නාමික ශ්‍රිතයක් ලෙස සලකනු ඇත. Klassඔබ නම නොදෙන්නේ නම් ක්‍රෝම් එකකට පවා නම භාවිතා කළ නොහැකkls ශ්‍රිතයට .

    මාර්ගය වන විට, ඔබට printStackTrace විකල්පය වෙත යා හැකිය, {guess: true}නමුත් එසේ කිරීමෙන් මට සැබෑ දියුණුවක් හමු නොවීය.

  3. සියලුම බ්‍රව්සර් ඔබට එකම තොරතුරු ලබා නොදේ. එනම්, පරාමිතීන්, කේත තීරුව යනාදිය.


අමතන්නාගේ ක්‍රියාකාරිත්වයේ නම

මාර්ගය වන විට, ඔබට අවශ්‍ය වන්නේ ඇමතුම් ශ්‍රිතයේ නම පමණි (බොහෝ බ්‍රව්සර් වල, නමුත් IE නොවේ) ඔබට භාවිතා කළ හැකිය:

arguments.callee.caller.name

නමුත් මෙම නම functionයතුරු පදයට පසුව ඇති බව සලකන්න . සමස්ත කාර්යයේ කේතය ලබා නොගෙන ඊට වඩා වැඩි යමක් ලබා ගැනීමට මට (ගූගල් ක්‍රෝම් හි පවා) ක්‍රමයක් හමු නොවීය.


අමතන්නාගේ ක්‍රියාකාරී කේතය

ඉතිරි හොඳම පිළිතුරු සාරාංශගත කිරීම (පැබ්ලෝ කබ්රෙරා, නූර්ඩින් සහ ග්‍රෙග් හෙව්ගිල් විසිනි). ඔබට භාවිතා කළ හැකි එකම හරස් බ්‍රව්සරය සහ සැබවින්ම ආරක්ෂිත දෙය නම්:

arguments.callee.caller.toString();

එමඟින් ඇමතුම් ශ්‍රිතයේ කේතය පෙන්වනු ඇත . කනගාටුවට කරුණක් නම්, එය මට ප්‍රමාණවත් නොවන අතර, ඒ නිසා මම ඔබට ස්ටැක්ට්‍රේස් සහ ඇමතුම් ශ්‍රිතයේ නම සඳහා ඉඟි ලබා දෙමි (ඒවා හරස් බ්‍රව්සරයක් නොවුවද).


1
සමහර විට ඔබ එකතු කළ යුතු Function.callerඑක් ග්රෙග් ගේ පිළිතුර @
Zach Lysobey

Function.callerකෙසේ වෙතත්, දැඩි ආකාරයෙන් ක්‍රියා නොකරනු ඇත.
රිකාඩ් එලිමේ

56

ඔබ "ජාවාස්ක්‍රිප්ට් හි" සඳහන් කර ඇති බව මම දනිමි, නමුත් අරමුණ නිදොස් කිරීම නම්, ඔබගේ බ්‍රව්සරයේ සංවර්ධක මෙවලම් භාවිතා කිරීම පහසු යැයි මම සිතමි. ක්‍රෝම් හි එය පෙනෙන්නේ මෙයයි: රූප විස්තරය මෙහි ඇතුළත් කරන්න ඔබට තොගය විමර්ශනය කිරීමට අවශ්‍ය තැන නිදොස්කරණය කරන්න.


3
මෙය පැරණි ප්‍රශ්නයකි ... නමුත් මෙය නියත වශයෙන්ම අද මෙය සිදු කිරීමේ නවීනතම වලංගු ක්‍රමයයි.
markstewie

53

නැවත සැකසීමට (සහ එය වඩාත් පැහැදිලි කරන්න) ...

මෙම කේතය:

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

මෙයට සමාන වේ:

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

පැහැදිලිවම පළමු බිට් වඩාත් අතේ ගෙන යා හැකි ය, මන්ද ඔබට ශ්‍රිතයේ නම වෙනස් කළ හැකි බැවින්, "හෙලෝ" සිට "සියාඕ" ලෙස පවසන්න, සහ තවමත් වැඩ කිරීමට සියල්ලම ලබා ගන්න.

දෙවැන්න නම්, ඔබ ආයාචිත ශ්‍රිතයේ නම (හෙලෝ) ප්‍රතිනිර්මාණය කිරීමට තීරණය කළහොත්, ඔබට එහි සියලු සිදුවීම් වෙනස් කිරීමට සිදුවේ :(


7
Chrome 25.0.1364.5 dev
Kokizzu

53

ඔබට සම්පූර්ණ සිරස් තලය ලබා ගත හැකිය:

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

අමතන්නා තෙක් null .

සටහන: එය පුනරාවර්තන කාර්යයන් මත අසීමිත පුඩුවක් ඇති කරයි.


2
ප්‍රමාද වූ පිළිතුරට කණගාටුයි, නමුත් මම ඔබේ අදහස මීට පෙර දැක නැත; පුනරාවර්තන අවස්ථාව සඳහා පමණක් එය ක්‍රියා නොකරයි, වෙනත් අවස්ථාවලදී එය ක්‍රියාත්මක විය යුතුය.
ale5000

48

මම සාමාන්‍යයෙන් භාවිතා කරමි (new Error()).stack Chrome හි . හොඳ දෙය නම්, මෙය ඔබට ඇමතුම ශ්‍රිතය ලෙස හැඳින්වෙන රේඛා අංක ද ලබා දීමයි. අවාසිය නම්, එය තොගයේ දිග 10 දක්වා සීමා කිරීමයි, මේ නිසා මම මෙම පිටුවට මුලින්ම ආවෙමි.

.


කරුණාකර ඔබ සපයන පැහැදිලි කිරීම ගැන තවත් විස්තරයක් එක් කළ හැකිද?
abarisone

6
ක්‍රියාත්මක වන විට මට වැඩට යා හැකි එකම දෙය 'use strict';මෙයයි. මට අවශ්‍ය තොරතුරු මට දුන්නා - ස්තූතියි!
ජෙරමි හැරිස්

5
තොගයේ දිග සම්බන්ධයෙන් ... ඔබට එය "Error.stackTraceLimit = Infinity" සමඟ වෙනස් කළ හැකිය.
ටොම්

(නව දෝෂය ("StackLog")). stack.split ("\ n") කියවීම වඩාත් සුදුසු කරයි.
Teoman shipahi

37

ඔබ එය IE <11 හි ධාවනය නොකරන්නේ නම් console.trace () ගැලපේ.

function main() {
    Hello();
}

function Hello() {
    console.trace()
}

main()
// Hello @ VM261:9
// main @ VM261:4

22

ඇමතුම් කාර්යය ලබා ගැනීම සඳහා ඔබට Function.Caller භාවිතා කළ හැකිය. Argument.caller භාවිතා කරන පැරණි ක්‍රමය යල් පැන ගිය එකක් ලෙස සැලකේ.

පහත කේතය එහි භාවිතය විදහා දක්වයි:

function Hello() { return Hello.caller;}

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

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

යල්පැනගිය තර්කය.කොලර් පිළිබඳ සටහන්: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller

Function.caller සම්මත නොවන බව මතක තබා ගන්න: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller


1
මේ දිනවල නිවැරදි පිළිතුර මෙයයි. ඔබට තවදුරටත් තර්ක.කොලර්.කලී දේවල් කළ නොහැක. අනෙක් සියල්ලම යල් පැන ගිය බැවින් අපට මෙය ඉහළට ගෙන යාමට හැකි වේවායි ප්‍රාර්ථනා කරමු.
coblr

4
දැඩි ප්‍රකාරයේදී මෙය කළ නොහැකි බව පෙනේ? Cannot access caller property of a strict mode function
සාක් ලයිසෝබි

Function.caller මා වෙනුවෙන් දැඩි ආකාරයකින් ක්‍රියා කළේ නැත. එසේම, MDN ට අනුව , function.caller සම්මත නොවන අතර එය නිෂ්පාදනයේදී භාවිතා නොකළ යුතුය. එය නිදොස්කරණය සඳහා ක්‍රියා කළ හැකිය.
jkdev

ප්‍රමිතිගත නොවන එය නෝඩ් හි වැඩ කරන්නේ නම් මට කිසිදු ගැටළුවක් නොතිබුණි, නමුත් එය දැඩි ප්‍රකාරයේදී අවසර නැත (මම 6.10 නෝඩ් එකෙන් පරීක්ෂා කළෙමි). 'තර්ක' සඳහා ද එය අදාළ වේ. මට දෝෂ පණිවිඩයක් ලැබුණි: '' 'අමතන්නා' සහ 'තර්ක' යනු සීමිත ක්‍රියාකාරී ගුණාංග වන අතර මෙම සන්දර්භය තුළ ඒවාට ප්‍රවේශ විය නොහැක. "
ටොම්

21

මම මෙය කරන්නෙමි:

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

මෙය විශිෂ්ටයි! වෙනත් ක්‍රම පැරණි බැවින් නිවැරදි පිළිතුර ලෙස පිළිගත යුතුය \ තවදුරටත් ක්‍රියා නොකරන්න
යුවල් ප්‍රස්

19
function Hello() {
    alert(Hello.caller);
}

1
ශ්‍රිතයේ නම සඳහා Hello.caller.name
vanval

සමානarguments.callee.caller.toString()
user2720864

මෙය නිවැරදි පිළිතුර විය යුතුය, අවම වශයෙන් 2016 සඳහා
ඩැනියෙල්

මෙය ප්‍රමිති මාර්ගයක නොවේ, නමුත් ECMAScript 5 වන විට ක්‍රියාත්මක වේ.
ඔබින්නා නවාක්වු

1
An ඩැනියෙල්: නැහැ, එසේ නොවිය යුතුයි. ශුද්ධාසනයේ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
දාන් Dascalescu

18

එය භාවිතා කිරීමට ආරක්ෂිත තියෙන්නේ *arguments.callee.callerසිට arguments.callerඇත නොසලකා හරිනු ...


36
arguments.calleeES5 හි ද ඉවත් කර ඇති අතර දැඩි ආකාරයෙන් ඉවත් කරනු ලැබේ.
nyuszika7h

2
විකල්පයක් තිබේද? සංස්කරණය කරන්න: arguments.calleeදැන් වඩාත් හොඳින් විසඳා ඇති බවට ගැටලුව නරක විසඳුමක් වූ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
මතෙව්

17

මෙය තරමක් විසඳා ඇති ප්‍රශ්නයක් සේ පෙනේ, නමුත් මෑතදී මම දැනගත්තා, 'දැඩි මාදිලියේ' ඇමතුම් සඳහා අවසර නැති බව, එබැවින් මගේ භාවිතය සඳහා මම පන්තියක් ලිවූ අතර එය හැඳින්වෙන ස්ථානයෙන් මාර්ගය ලැබෙනු ඇත. එය කුඩා සහායක ලිබ් එකක කොටසක් වන අතර ඔබට කේතය තනිවම භාවිතා කිරීමට අවශ්‍ය නම් ඇමතුම්කරුගේ තොග හෝඩුවාව ආපසු ලබා දීමට භාවිතා කරන ඕෆ්සෙට් එක වෙනස් කරන්න (2 වෙනුවට 1 භාවිතා කරන්න)

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('.');
  };
}

function a(){ function b(){ function c(){ return ScriptPath(); } return c(); } return b(); } a()කොන්සෝලය තුළ මා සමඟ වැඩ නොකරයි (ගොනුවක උත්සාහ කර නැත), නමුත් සාධාරණ අදහසක් ඇති බව පෙනේ. දෘශ්‍යතාව සඳහා කෙසේ හෝ ඉහළට ඔසවා තැබිය යුතුය.
ninjagecko

අදහස විශිෂ්ටයි. මම වෙනස් ආකාරයකින් විග්‍රහ කර ඇති නමුත් nw.js යෙදුම් වල, ඇත්ත වශයෙන්ම මා සොයන දේ ලබා දෙන එකම අදහස මෙයයි.
ඇන්ඩ rew ග්‍රෝත්

කරුණාකර මෙම ශ්‍රිතය අමතන්නේ කෙසේද යන්න පිළිබඳ උදාහරණයක් සපයන්න.
pd_au

13

ES6 සහ දැඩි ප්‍රකාරයේදී, අමතන්නාගේ ක්‍රියාකාරිත්වය ලබා ගැනීමට පහත සඳහන් දෑ භාවිතා කරන්න

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

අමතන්නෙකු හෝ පෙර තොගයක් නොමැති නම්, ඉහත රේඛාව ව්‍යතිරේකයක් විසි කරන බව කරුණාවෙන් සලකන්න. ඒ අනුව භාවිතා කරන්න.

අමතන්න (වර්තමාන ශ්‍රිතයේ නම), භාවිතා කරන්න:

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

12

කොන්සෝලය ඔබගේ දෝෂ තොගය ලොග් කරන්න. එවිට ඔබව දැන ගන්නේ කෙසේද?

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

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

sello()



11

2018 යාවත්කාලීන කිරීම

caller දැඩි ආකාරයෙන් තහනම් කර ඇත . මෙන්න (සම්මත නොවන) Errorතොගය භාවිතා කරන විකල්පයක් .

පහත දැක්වෙන ශ්‍රිතය ෆයර්ෆොක්ස් 52 සහ ක්‍රෝම් 61-71 හි කාර්යය ඉටු කරන බවක් පෙනෙන්නට තිබුණද, එය ක්‍රියාත්මක කිරීම බ්‍රව්සර් දෙකේ ලොග් වීමේ ආකෘතිය පිළිබඳව බොහෝ උපකල්පන සිදු කරන අතර එය පරිස්සමෙන් භාවිතා කළ යුතුය. සිදු කිරීමට පෙර ගැලපීම්.

'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
එය ඇදහිය නොහැකි මෙන්ම භයානක ය.
ඉයන්

මට "foo called with: hi there" ලැබුණා, නමුත් foo "hi there" ලෙස නම් කර නැත, "hi there" සමඟ ලොග් කැඳවනු ලැබීය
ඇන්ඩ rewR

හරි, දෝෂ පණිවිඩයේ ව්‍යාකරණයේ “අස්ථානගත විකරණකාරකයක්” තිබුණි. එහි අර්ථය "ලොග් කැඳවනු ලැබුවේ එෆ් ශ්‍රිතයෙන්, එයට X පණිවිඩය මුද්‍රණය කිරීමට අවශ්‍ය විය" නමුත් හැකි තරම් සංක්ෂිප්ත ආකාරයකින්.
රොවනියන්

7

මේ සඳහා මගේ ෆෙඩල් මෙහි එක් කිරීමට මට අවශ්‍ය විය:

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

මෙය ක්‍රෝම්, සෆාරි සහ අයිඊ (10 සහ 8) බව මම පරීක්ෂා කළෙමි. හොඳින් වැඩ කරයි. වැදගත් වන්නේ ශ්‍රිත 1 ක් පමණි, එබැවින් ඔබ විශාල ප්‍රහේලිකාවෙන් බිය වන්නේ නම්, පහත කියවන්න.

සටහන: මෙම ෆෙඩලය තුළ මගේම “බොයිලර් ප්ලේට්” හි සාධාරණ ප්‍රමාණයක් තිබේ. ඔබට ඒ සියල්ල ඉවත් කර ඔබ කැමති නම් බෙදීම් භාවිතා කළ හැකිය. එය අතිශයින්ම ආරක්ෂිත "මා විශ්වාස කළ යුතු කාර්යයන් සමූහයකි.

"ජේඑස්ෆිඩල්" අච්චුවක් ද එහි ඇත, මම බොහෝ ෆිද්ල්ස් සඳහා ඉක්මන් විකාරයක් භාවිතා කරමි.


සමහර අවස්ථාවල මූලාකෘති සඳහා දිගු ලෙස "උදව්කරුවන්" එකතු කළ හැකිදැයි මම කල්පනා කරමි, උදාහරණයක් ලෙස:String.prototype.trim = trim;
ඔටිස්ටික්

6

ඔබට අවශ්‍ය වන්නේ ක්‍රියාකාරී නාමය මිස කේතය නොවේ නම් සහ බ්‍රව්සරයෙන් ස්වාධීන විසඳුමක් අවශ්‍ය නම්, පහත සඳහන් දෑ භාවිතා කරන්න:

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

අරාවෙහි [1] මූලද්‍රව්‍යයක් නොමැති බැවින් ඇමතුම් ශ්‍රිතයක් නොමැති නම් ඉහත සඳහන් දෝෂයක් නැවත ලබා දෙන බව සලකන්න. වැඩ කිරීමට, පහත භාවිතා කරන්න:

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

හෙයිස්වාර්ට්ගේ පිළිතුර සහ ජියරොන්ග්වුගේ පිළිතුර යන දෙකම සඳහන් කළේ Errorවස්තුවට ප්‍රවේශය ඇති බවයි stack.

මෙන්න උදාහරණයක්:

function main() {
  Hello();
}

function Hello() {
  var stack = new Error().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();

විවිධ බ්‍රව්සර් මඟින් විවිධ තන්තු ආකෘතිවල තොගය පෙන්වයි:

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)

බොහෝ බ්‍රව්සර් සමඟ තොගය සකසනු ඇත var stack = (new Error()).stack. ඉන්ටර්නෙට් එක්ස්ප්ලෝරර් හි තොගය නිර්වචනය නොකෙරේ - තොගය නැවත ලබා ගැනීම සඳහා ඔබට සැබෑ ව්‍යතිරේකයක් දැමිය යුතුය.

නිගමනය: එනම්, "ප්රධාන" තීරණය කිරීම සඳහා හැකි වන්නේ, එම භාවිතා වන "හෙලෝ" වෙත මේ? මෙයාට stackතුළ Errorවස්තුව. ඇත්ත වශයෙන්ම එය callee/ callerප්රවේශය ක්රියා නොකරන අවස්ථාවන්හිදී ක්රියා කරනු ඇත. එය ඔබට සන්දර්භය, එනම් ප්‍රභව ගොනුව සහ පේළි අංකය පෙන්වනු ඇත. කෙසේ වෙතත් විසඳුම හරස් වේදිකාවක් බවට පත් කිරීමට උත්සාහ කිරීම අවශ්‍ය වේ.


4

මෙන්න, රෙජෙක්ස්ප් සමඟ හැර අනෙක් සියල්ල functionnameඉවත් කර ඇත caller.toString().

<!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>

මෙය තවමත් සම්පූර්ණ ක්‍රම ප්‍රකාශය නැවත ලබා දෙයි
මැස්ලෝ


2

ඔබට Node.js හි Function.caller භාවිතා කළ නොහැකි බව සලකන්න , ඒ වෙනුවට caller -id පැකේජය භාවිතා කරන්න. උදාහරණයක් වශයෙන්:

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

පහත කේතය උත්සාහ කරන්න:

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;
}

ෆයර්ෆොක්ස් -21 සහ ක්‍රෝමියම් -25 හි මා වෙනුවෙන් වැඩ කළා.


පුනරාවර්තන කාර්යයන් සඳහා මෙය උත්සාහ කරන්න.
daniel1426


1

මෙම ගැටළුව වටා ඇති තවත් ක්‍රමයක් නම් ඇමතුම් ශ්‍රිතයේ නම පරාමිතියක් ලෙස සම්මත කිරීමයි.

උදාහරණයක් වශයෙන්:

function reformatString(string, callerName) {

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

    return string;
}

දැන්, ඔබට ශ්‍රිතය මේ ආකාරයට හැඳින්විය හැකිය:

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

    reformatString(myString, function.name);
}

මගේ උදාහරණය මඟින් ශ්‍රිතයේ නම කේතනය කරන ලද චෙක්පතක් භාවිතා කරයි, නමුත් ඔබට එහි අවශ්‍ය දේ කිරීමට පහසුවෙන් ස්විච් ප්‍රකාශයක් හෝ වෙනත් තර්කනයක් භාවිතා කළ හැකිය.


මෙය බොහෝ දුරට හරස් බ්‍රව්සර් අනුකූලතා ගැටලු ද විසඳනු ඇතැයි මම විශ්වාස කරමි. නමුත් මෙය සත්‍ය යැයි උපකල්පනය කිරීමට පෙර කරුණාකර මෙය පරීක්ෂා කරන්න! ( දහඩිය දැමීමට පටන් ගනී )
ග්‍රේඩ් ෆොක්ස්

1

මා දන්නා පරිදි, මේ සඳහා ලබා දී ඇති ප්‍රභවයන්ගෙන් අපට මේ සඳහා ක්‍රම 2 ක් ඇත-

  1. argument.caller

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

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

ඔබේ පිළිතුර ඔබ සතුව ඇතැයි සිතන්න :).


මෙය වසර ගණනාවක් තිස්සේ අවලංගු කර ඇති අතර Function.caller දැඩි ආකාරයකින් ක්‍රියා නොකරයි.
ඩෑන් ඩස්කල්ස්කු

1

ඉහත සියලු විසඳුම් රොකට් විද්‍යාවක් ලෙස පෙනෙන්නේ ඇයි. මේ අතර, එය මෙම ස්නිපටයට වඩා සංකීර්ණ නොවිය යුතුය. සියලුම ගෞරව මෙම පුද්ගලයාට

ජාවාස්ක්‍රිප්ට් හි ඇමතුම් ශ්‍රිතය ඔබ සොයා ගන්නේ කෙසේද?

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
මෙය භාවිතා කිරීමෙන් මට ලැබෙන්නේ මෙයයි: TypeError: 'caller', 'callee', සහ 'තර්ක' ගුණාංග දැඩි මාදිලියේ ක්‍රියාකාරිත්වයන් හෝ ඒවාට ඇමතුම් සඳහා වන තර්ක වස්තු වෙත ප්‍රවේශ නොවිය හැකිය. කිසියම් අදහසක් මෙය දැඩි ආකාරයකින් ක්‍රියාත්මක කරන්නේ කෙසේද?
hard_working_ant

1

මම මෙම ප්‍රශ්නය සමඟ ප්‍රශ්නය සහ වර්තමාන ත්‍යාගය යන දෙකම ආමන්ත්‍රණය කිරීමට උත්සාහ කරමි.

ත්‍යාගයෙන් ඉල්ලා සිටින්නේ අමතන්නා දැඩි ප්‍රකාරයෙන් ලබා ගත යුතු අතර , මෙය සිදු කර ඇති ආකාරය මට දැකගත හැකි එකම ක්‍රමය වන්නේ දැඩි ප්‍රකාරයෙන් පිටත ප්‍රකාශිත ශ්‍රිතයක් යොමු කිරීමයි .

උදාහරණයක් ලෙස, පහත දැක්වෙන්නේ සම්මත නොවන නමුත් පෙර (29/03/2016) සහ වර්තමාන (2018 අගෝස්තු 1) ක්‍රෝම්, එජ් සහ ෆයර්ෆොක්ස් අනුවාද සමඟ පරීක්ෂා කර ඇත.

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();


හොඳ හැක්, නමුත් සම්පූර්ණයෙන්ම දැඩි මාදිලියේ ඇති ES5 මොඩියුල සඳහා ක්‍රියා නොකරනු ඇත .
ඩෑන් ඩස්කල්ස්කු

0

ඔබට කිසියම් හේතුවක් නිසා ක්‍රියාකාරීත්වය අවශ්‍ය නම් සහ එය හරස් බ්‍රව්සරයට අනුකූල වීමට අවශ්‍ය නම් සහ දැඩි දේවල් ගැන කරදර නොවී ඉදිරියට අනුකූල වීමට අවශ්‍ය නම් මෙම යොමු කිරීම සම්මත කරන්න:

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

පහත කේත කෑල්ල ප්‍රයෝජනවත් විය හැකි යැයි මම සිතමි:

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);
}

කේතය ක්‍රියාත්මක කරන්න:

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();

ලොගය මේ වගේ ය:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.