আমি কি এখন জাভাস্ক্রিপ্টে চলমান ফাংশনটির নাম পেতে পারি?


184

এটা করা কি সম্ভব:

myfile.js:
function foo() {
    alert(<my-function-name>);
    // pops-up "foo"
    // or even better: "myfile.js : foo"
}

আমার স্ট্যাকের মধ্যে আমি ডোজো এবং জিকুয়েরি ফ্রেমওয়ার্ক পেয়েছি, সুতরাং তাদের মধ্যে যদি কেউ এটি সহজ করে তোলে তবে সেগুলি উপলব্ধ।

উত্তর:


196

ES5 এবং এর উপরে, তথ্যের কোনও অ্যাক্সেস নেই।

জেএস এর পুরানো সংস্করণগুলিতে আপনি এটি ব্যবহার করে এটি পেতে পারেন arguments.callee

আপনাকে নামটি বিশ্লেষণ করতে হতে পারে যদিও এটিতে কিছু অতিরিক্ত জাঙ্ক অন্তর্ভুক্ত থাকবে। যদিও কিছু বাস্তবায়নে আপনি নামটি সহজেই ব্যবহার করতে পারেন arguments.callee.name

পার্সিং:

function DisplayMyName() 
{
   var myName = arguments.callee.toString();
   myName = myName.substr('function '.length);
   myName = myName.substr(0, myName.indexOf('('));

   alert(myName);
}

উত্স: জাভাস্ক্রিপ্ট - বর্তমান ফাংশন নাম পান


প্রকৃতপক্ষে, আপনার প্রশ্নের দিকে আরও মনোযোগ দিচ্ছেন, মনে হচ্ছে আপনি অতিরিক্ত জাঙ্কটি পেতে পারেন :)
ম্যাট

23
@ অ্যান্ড্রু - আপনি ঠিক বলেছেন, আমার এটা বলা উচিত ছিল। এটি আমি ইতিমধ্যে বুকমার্ক করে রেখেছিলাম এমন কিছুর একটি দ্রুত অনুলিপি / পেস্ট / ক্লিনআপ এবং আমার পক্ষ থেকে একটি তদারকি ছিল। এটি আমার পোস্টে যুক্ত করার জন্য আপনাকে ধন্যবাদ।
ম্যাট

81
ES5 কঠোর মোডে বিরতি।
রায়নোস

4
ওহ ... এই কারণেই লোকেরা আমাকে উত্তর দেওয়ার গতিতে সর্বদা মারধর করে। আমি এটা ভাবিনি।
এরিক রেপেন

9
আপনি যদি আপনার পদ্ধতিগুলির জন্য কোনও অবজেক্ট আক্ষরিক ব্যবহার করেন এবং কোনও প্রকৃত পদ্ধতির নাম ব্যবহার করেন না, তবে এটি আর্গুমেন্ট হিসাবে কাজ করবে না al আপনাকে নিশ্চিত করতে হবে যে আপনি এই ফাংশনটির নামটি দুবার যুক্ত করেছেন। এই jsfiddle উদাহরণটি দেখুন: jsfiddle.net/ncays । এটির সাথে আর একটি সমস্যা যদিও এটি arguments.calleeকঠোর মোডের অধীনে অনুমোদিত নয়।
হেল্লাতান

75

অজ্ঞাতনামা ফাংশনের জন্য

function foo()
{ 
    alert(arguments.callee.name)
}

তবে কোনও ত্রুটি হ্যান্ডলারের ক্ষেত্রে ফলাফলটি ত্রুটি হ্যান্ডলারের ফাংশনটির নাম হবে, তাই না?


2
ক্রোমে দুর্দান্ত কাজ করে। গৃহীত উত্তরের চেয়ে অনেক বেশি ভাল।
বি সেভেন

1
মনে রাখবেন মূল্যবান: eslint.org/docs/rules/no-caller > "জাভাস্ক্রিপ্টের ভবিষ্যতের সংস্করণগুলিতে অবচয় করা হয়েছে এবং কঠোর মোডে থাকাকালীন ECMAScript 5 এ তাদের ব্যবহার নিষিদ্ধ।"
জেরেমি

45

আপনার যা প্রয়োজন তা সহজ। ফাংশন তৈরি করুন:

function getFuncName() {
   return getFuncName.caller.name
}

এর পরে যখনই আপনার প্রয়োজন হবে, আপনি কেবল ব্যবহার করুন:

function foo() { 
  console.log(getFuncName())
}

foo() 
// Logs: "foo"

3
ধন্যবাদ, এটি স্ট্রিংকে পার্স করার চেয়ে অনেক বেশি মার্জিত।
modle13

1
এটি সেরা উত্তর বলে মনে হচ্ছে!
সের্গেই

পারফেক্ট। তখন যখন
জেএসের কাছে

ক্রোম আমাকে এক ধরণের ত্রুটি দেয় কারণ কলারের উপরে সম্পত্তি 'নাম' বিদ্যমান নেই। যাইহোক, পরিদর্শন থেকে প্রমাণিত হয়েছে যে এটি কাজ করেছে:function getFuncName() { return getFuncName.name }
টম অ্যান্ডারসন

@ টমএন্ডারসন আপনার পরিবর্তনের সাথে সাথে আপনি এখন তার আহ্বানকের নামের getFuncNameচেয়ে নামটি পাচ্ছেন ।
মার্ক ম্যাকেন্না

30

এমডিএন অনুসারে

সতর্কতা: ECMAScript (ES5) এর 5 তম সংস্করণটি কঠোর মোডে আর্গুমেন্টস.ক্যালি () ব্যবহার নিষিদ্ধ করেছে। ফাংশন এক্সপ্রেশনকে একটি নাম দিয়ে বা যুক্তিগুলি যে কোনও ফাংশনটি নিজেকে কল করতে হবে সেখানে কোনও ফাংশন ঘোষণার ব্যবহার করে আর্গুমেন্টস.ক্যালি () ব্যবহার করা এড়িয়ে চলুন।

যেমন উল্লেখ করা হয়েছে এটি কেবল তখনই প্রযোজ্য যদি আপনার স্ক্রিপ্টটি "কঠোর মোড" ব্যবহার করে। এটি মূলত সুরক্ষার কারণে এবং দুঃখের সাথে বর্তমানে এর কোনও বিকল্প নেই।


21

এটি করা উচিত:

var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);

কলারের জন্য, কেবল ব্যবহার করুন caller.toString()


8
এটি আমার পক্ষে কাজ করেছে তবে আমি মনে করি আপনার রেজিপেক্সে একটি টাইপ রয়েছে। [
ডিক্লান এর

4
@ ডেক্লান: হ্যাঁ, আপনি ঠিক বলেছেন অবাক করার মতো বিষয়টি অন্য কেউই বলেন নি যে প্রায় 3 বছরে এই উত্তরটি এখানে এসেছে :-)
অ্যান্ডি ই

@ অ্যান্ডি সম্ভবত কেউ এটিকে দেখায়নি কারণ একবার আমরা যখন রেজিএক্সএক্স দেখি, আমরা টিএল; ডিআর মোডে প্রবেশ করি এবং অন্যান্য উত্তরগুলি সন্ধান করি;)
বিটিক্লার

11

এটি "বিশ্বের কদর্য হ্যাক" বিভাগে যেতে হবে, তবে আপনি এখানে যান।

প্রথমত, বর্তমান ফাংশনটির নাম মুদ্রণ করা (অন্য উত্তরগুলির মতো) মনে হয় আমার কাছে সীমিত ব্যবহার রয়েছে, কারণ আপনি যে ধরনের কাজ ইতিমধ্যে জানেন তা কী!

তবে, কলিং ফাংশনটির নাম খুঁজে পাওয়া কোনও ট্রেস ফাংশনের জন্য বেশ কার্যকর হতে পারে। এটি একটি রেজিপেক্সের সাথে, তবে সূচিপত্র ব্যবহার করা প্রায় 3x দ্রুত হবে:

function getFunctionName() {
    var re = /function (.*?)\(/
    var s = getFunctionName.caller.toString();
    var m = re.exec( s )
    return m[1];
}

function me() {
    console.log( getFunctionName() );
}

me();

দুর্দান্ত সমাধান, তবে এফওয়াইআই ফাংশন # কলার অ-মানক বিকাশকারী.মোজিলা.আর.ইন-
ইউএস / ডকস / ওয়েব / জাভা স্ক্রিপ্ট / রেফারেন্স /…

বর্তমান ফাংশনটির নাম জানা অপরিহার্য হতে পারে যদি সেই ফাংশনটি একটি ডাটাবেস থেকে গতিশীলভাবে তৈরি করা হয় এবং ফাংশনের নামের সাথে কীযুক্ত ফাংশনের অভ্যন্তরের প্রসঙ্গের তথ্য প্রয়োজন হয়।
পল চেরনোচ

9

এখানে একটি উপায় যা কাজ করবে:

export function getFunctionCallerName (){
  // gets the text between whitespace for second part of stacktrace
  return (new Error()).stack.match(/at (\S+)/g)[1].slice(3);
}

তারপরে আপনার পরীক্ষায়:

import { expect } from 'chai';
import { getFunctionCallerName } from '../../../lib/util/functions';

describe('Testing caller name', () => {

    it('should return the name of the function', () => {
      function getThisName(){
        return getFunctionCallerName();
      }

      const functionName = getThisName();

      expect(functionName).to.equal('getThisName');
    });

  it('should work with an anonymous function', () => {


    const anonymousFn = function (){
      return getFunctionCallerName();
    };

    const functionName = anonymousFn();

    expect(functionName).to.equal('anonymousFn');
  });

  it('should work with an anonymous function', () => {
    const fnName = (function (){
      return getFunctionCallerName();
    })();

    expect(/\/util\/functions\.js/.test(fnName)).to.eql(true);
  });

});

নোট করুন যে তৃতীয় পরীক্ষাটি কেবল তখনই কাজ করবে যখন পরীক্ষাটি / ব্যবহার / ফাংশনে অবস্থিত in


7

getMyNameফাংশন আয় নিচে snippet কলিং ফাংশন নাম। এটা একটা হ্যাক এবং উপর নির্ভর করে অ-মানক বৈশিষ্ট্য: Error.prototype.stack। নোট করুন যে ফেরত স্ট্রিংয়ের ফর্ম্যাটটি Error.prototype.stackবিভিন্ন ইঞ্জিনে আলাদাভাবে প্রয়োগ করা হয়েছে, সুতরাং এটি সম্ভবত সর্বত্র কাজ করবে না:

function getMyName() {
  var e = new Error('dummy');
  var stack = e.stack
                .split('\n')[2]
                // " at functionName ( ..." => "functionName"
                .replace(/^\s+at\s+(.+?)\s.+/g, '$1' );
                return stack
}

function foo(){
  return getMyName()
}

function bar() {
  return foo()
}

console.log(bar())

অন্যান্য সমাধানের সম্পর্কে: arguments.callee কঠোর মোডে মঞ্জুরিপ্রাপ্ত নয় এবং Function.prototype.callerহয় অ-মানক এবং কঠোর মোডে মঞ্জুরিপ্রাপ্ত নয়


ফাংশনে অবস্থান প্রদর্শন করতে এবং বেনামে ফাংশনগুলি সমর্থন করে এর সাথে প্রসারিত করুন: ?))? $ / জি, '$ 1 ($ 2: $ 3)')
কোফিফাস

ফাংশন.প্রোটোটাইপ.কমারকে কঠোর মোডেও অনুমোদিত নয়।
ফিজিয়ারাওন

1
এমনকি তীর ফাংশন, আন্ডাররেটেড উত্তরগুলির জন্যও নিখুঁত কাজ করে
হাও উউ

3

আর একটি ব্যবহারের ক্ষেত্রে রানটাইমের সময় আবদ্ধ ইভেন্ট প্রেরণকারী হতে পারে:

MyClass = function () {
  this.events = {};

  // Fire up an event (most probably from inside an instance method)
  this.OnFirstRun();

  // Fire up other event (most probably from inside an instance method)
  this.OnLastRun();

}

MyClass.prototype.dispatchEvents = function () {
  var EventStack=this.events[GetFunctionName()], i=EventStack.length-1;

  do EventStack[i]();
  while (i--);
}

MyClass.prototype.setEvent = function (event, callback) {
  this.events[event] = [];
  this.events[event].push(callback);
  this["On"+event] = this.dispatchEvents;
}

MyObject = new MyClass();
MyObject.setEvent ("FirstRun", somecallback);
MyObject.setEvent ("FirstRun", someothercallback);
MyObject.setEvent ("LastRun", yetanothercallback);

এখানে সুবিধাটি প্রেরণকারীর সহজেই পুনরায় ব্যবহার করা যেতে পারে এবং একটি আর্গুমেন্ট হিসাবে প্রেরণের সারিটি গ্রহণ করতে হবে না, পরিবর্তে এটি অনুরোধের নামের সাথে জড়িত ...

শেষ অবধি, এখানে উপস্থাপিত সাধারণ কেসটি হ'ল "ফাংশনটির নামটি একটি যুক্তি হিসাবে ব্যবহার করা হবে যাতে আপনাকে এটি স্পষ্টভাবে পাস করতে হবে না", এবং এটি জ্যাকারি অ্যানিমেট () alচ্ছিক কলব্যাকের মতো অনেক ক্ষেত্রে কার্যকর হতে পারে, বা সময়সীমা / অন্তর কলব্যাকগুলিতে, (যেমন আপনি কেবল একটি ফানসিওন পাস করেন)।


2

বর্তমান ফাংশনটির নাম এবং এটি কীভাবে পাওয়া যায় তা এই প্রশ্ন জিজ্ঞাসা করার পরে, গত 10 বছরে পরিবর্তিত হয়েছে বলে মনে হচ্ছে।

এখন, প্রো প্রো ওয়েব বিকাশকারী না হয়ে যিনি এখনও উপস্থিত সমস্ত ব্রাউজারের সমস্ত ইতিহাস সম্পর্কে জানেন, 2019 ক্রোম ব্রাউজারে এটি আমার জন্য কীভাবে কাজ করবে তা এখানে রয়েছে:

function callerName() {
    return callerName.caller.name;
}
function foo() {
    let myname = callerName();
    // do something with it...
}

অন্যান্য উত্তরগুলির মধ্যে কয়েকটি কঠোর জাভাস্ক্রিপ্ট কোড এবং হোয়াট নোট সম্পর্কে ক্রোম ত্রুটির মধ্যে ছড়িয়ে পড়ে।


1

যেহেতু আপনি নামের একটি ফাংশন লিখেছেন fooএবং আপনি জানেন যে এটিতে রয়েছেmyfile.js কেন আপনার এই তথ্যটি গতিশীলভাবে পাওয়ার প্রয়োজন?

বলা হচ্ছে আপনি ব্যবহার করতে পারেন arguments.callee.toString()এটি ফাংশনের অভ্যন্তরে (এটি পুরো ফাংশনের একটি স্ট্রিং উপস্থাপনা) এবং ফাংশনটির নামের মানটি

এখানে একটি ফাংশন যা তার নিজের নামটি থুতু দেবে:

function foo() {
    re = /^function\s+([^(]+)/
    alert(re.exec(arguments.callee.toString())[1]);             
}

5
আমি একটি ত্রুটি হ্যান্ডলারের উপর কাজ করছি, এবং আমি কলিং ফাংশনটি রিপোর্ট করতে চাই।
স্প্রুগম্যান

1

আমি এখানে দেখেছি কয়েকটি প্রতিক্রিয়া সংমিশ্রণ। (এফএফ, ক্রোম, আই 11 এ পরীক্ষিত)

function functionName() 
{
   var myName = functionName.caller.toString();
   myName = myName.substr('function '.length);
   myName = myName.substr(0, myName.indexOf('('));
   return myName;
}

function randomFunction(){
    var proof = "This proves that I found the name '" + functionName() + "'";
    alert(proof);
}

কলম এলোমেলোভাবে ফাংশন () ফাংশন নাম ধারণ করে একটি স্ট্রিং সতর্ক করবে।

জেএস ফিডাল ডেমো: http://jsfiddle.net/mjgqfhbe/


1

এটির আপডেট হওয়া উত্তরটি এই উত্তরটিতে পাওয়া যাবে: https://stackoverflow.com/a/2161470/632495

এবং, যদি আপনি ক্লিক করে মনে করেন না:

function test() {
  var z = arguments.callee.name;
  console.log(z);
}

1

তথ্য 2016 বছরের আসল।


ফাংশন ঘোষণার ফলাফল

অপেরাতে ফলাফল

>>> (function func11 (){
...     console.log(
...         'Function name:',
...         arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
... 
... (function func12 (){
...     console.log('Function name:', arguments.callee.name)
... })();
Function name:, func11
Function name:, func12

ক্রোমে ফলাফল

(function func11 (){
    console.log(
        'Function name:',
        arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
})();

(function func12 (){
    console.log('Function name:', arguments.callee.name)
})();
Function name: func11
Function name: func12

নোডজেএস-এ ফলাফল

> (function func11 (){
...     console.log(
.....         'Function name:',
.....         arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
Function name: func11
undefined
> (function func12 (){
...     console.log('Function name:', arguments.callee.name)
... })();
Function name: func12

ফায়ারফক্সে কাজ করে না। আইই এবং এজতে নিরীক্ষিত।


ফাংশন এক্সপ্রেশন জন্য ফলাফল

নোডজেএস-এ ফলাফল

> var func11 = function(){
...     console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11

ক্রোমে ফলাফল

var func11 = function(){
    console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11

ফায়ারফক্স, অপেরা তে কাজ করে না। আইই এবং এজতে নিরীক্ষিত।

মন্তব্য:

  1. বেনামে ফাংশনটি যাচাই করার কোনও মানে নেই।
  2. পরীক্ষার পরিবেশ

~ $ google-chrome --version
Google Chrome 53.0.2785.116           
~ $ opera --version
Opera 12.16 Build 1860 for Linux x86_64.
~ $ firefox --version
Mozilla Firefox 49.0
~ $ node
node    nodejs  
~ $ nodejs --version
v6.8.1
~ $ uname -a
Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

1
(function f() {
    console.log(f.name);  //logs f
})();

প্রকারের প্রকরণ:

function f1() {} 
function f2(f:Function) {
   console.log(f.name);
}

f2(f1);  //Logs f1

নোটগুলি কেবল ES6 / ES2015 অনুবর্তী ইঞ্জিনগুলিতে উপলব্ধ। আরও দেখুন


0

এখানে একটি ওলাইনার রয়েছে:

    arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')

এটার মত:

    function logChanges() {
      let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
      console.log(whoami + ': just getting started.');
    }

0

এটি ইগর ওস্ট্রোমভের একটি বৈকল্পিক উত্তরের :

আপনি যদি কোনও প্যারামিটারের জন্য এটি ডিফল্ট মান হিসাবে ব্যবহার করতে চান তবে আপনাকে 'কলার' এ দ্বিতীয় স্তরের কলটি বিবেচনা করতে হবে:

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

এটি গতিশীলভাবে একাধিক ফাংশনে পুনরায় ব্যবহারযোগ্য প্রয়োগের জন্য অনুমতি দেবে।

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

function bar(myFunctionName = getFunctionsNameThatCalledThisFunction())
{ 
  alert(myFunctionName);
}

// pops-up "foo"
function foo()
{
  bar();
}

function crow()
{
  bar();
}

foo();
crow();

আপনি যদি ফাইলের নামও চান, অন্য প্রশ্নের জন্য F-3000 থেকে উত্তরটি ব্যবহার করে এখানে সমাধানটি দেওয়া হল :

function getCurrentFileName()
{
  let currentFilePath = document.scripts[document.scripts.length-1].src 
  let fileName = currentFilePath.split('/').pop() // formatted to the OP's preference

  return fileName 
}

function bar(fileName = getCurrentFileName(),  myFunctionName = getFunctionsNameThatCalledThisFunction())
{
  alert(fileName + ' : ' + myFunctionName);
}

// or even better: "myfile.js : foo"
function foo()
{
  bar();
}


-7

উত্তরটি সংক্ষিপ্ত: alert(arguments.callee.name);


12
ফরাসি ভাষায় "নাম" হ'ল "নাম"। ব্রাউজারগুলির ভাষা সংস্করণগুলির মধ্যে কি এই ধরণের বিশদ পরিবর্তন হয়? আমি এটা ভাবেন না।
আর্কিল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.