JavaScript에서 현재 실행중인 함수의 이름을 얻을 수 있습니까?


184

이것을 할 수 있습니까?

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

내 스택에 Dojo 및 jQuery 프레임 워크가 있으므로 둘 중 하나가 더 쉬워지면 사용할 수 있습니다.

답변:


196

ES5 이상에서는 해당 정보에 액세스 할 수 없습니다.

이전 버전의 JS에서는을 사용하여 얻을 수 있습니다 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);
}

출처 : Javascript-현재 함수 이름을 가져옵니다 .


실제로, 실제로 귀하의 질문에 더 많은 관심을 기울이면 여분의 쓰레기를 원할 것 같습니다 :)
Matt

23
@Andrew-당신 말이 맞았습니다. 이미 북마크 한 항목을 빠르게 복사 / 붙여 넣기 / 정리하고 내 부분을 감독했습니다. 내 게시물에 추가해 주셔서 감사합니다.
Matt

81
ES5 엄격 모드에서 중단합니다.
Raynos

4
아 .. 그래서 사람들은 항상 대답하는 속도로 나를 이겼습니다. 나는 그것을 생각하지 않았다.
Erik Reppen

9
메소드에 객체 리터럴을 사용하고 실제 메소드 이름이 없으면 인수로 작동하지 않습니다. callee는 함수 이름을 포함하지 않는 익명 함수처럼 작동합니다. 해당 기능 이름을 두 번 추가해야합니다. 이 jsfiddle 예를 살펴 보자 : jsfiddle.net/ncays를 . 그러나 이것의 또 다른 문제 arguments.callee는 엄격 모드에서는 허용되지 않는다는 것입니다.
헬라 탄

75

비 익명 함수

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

그러나 오류 처리기의 경우 결과는 오류 처리기 함수의 이름이됩니까?


2
Chrome에서 잘 작동합니다. 허용 된 답변보다 훨씬 낫습니다.
B Seven

1
마음에 가치 베어링 : eslint.org/docs/rules/no-caller은 > "자바 스크립트의 미래 버전에서 사용되지 않는 자신의 사용은 동안 엄격한 모드 인 ECMAScript 5에서 금지되어 있습니다."
제레미

44

필요한 것은 간단합니다. 함수 만들기 :

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

그런 다음 필요할 때마다 다음을 사용하십시오.

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

foo() 
// Logs: "foo"

3
고마워, 이것은 문자열을 파싱하는 것보다 훨씬 우아합니다.
modle13

1
가장 좋은 답변 인 것 같습니다!
Sergey

완전한. PHP가 매직 상수를 사용하는 것처럼 JS가 네이티브 상수를 가지고 있지 않을 때입니다.
stamster

발신자에 'name'속성이 없으므로 Chrome에서 유형 오류가 발생합니다. 그러나, 검사 결과는 다음과 같이 작동 함이 밝혀졌습니다.function getFuncName() { return getFuncName.name }
Tom Anderson

@TomAnderson이 변경되면 이제 getFuncName발신자 의 이름이 아닌 이름을 얻습니다 .
마크 맥 케나

30

MDN 에 따르면

경고 : ECMAScript (ES5) 5 판에서는 엄격 모드에서 arguments.callee ()를 사용할 수 없습니다. 함수 표현식에 이름을 지정하거나 함수 자체를 호출해야하는 함수 선언을 사용하여 arguments.callee ()를 사용하지 마십시오.

언급했듯이 이것은 스크립트가 "엄격 모드"를 사용하는 경우 에만 적용 됩니다 . 이것은 주로 보안상의 이유이며 슬프게도 현재로서는 이에 대한 대안이 없습니다.


21

이것은해야합니다 :

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

발신자의 경우을 사용하십시오 caller.toString().


8
이것은 나를 위해 일했지만 정규 표현식에 오타가 있다고 생각합니다. [
12

4
@ declan : 네, 그렇습니다. 거의 3 년 동안이 해답이 여기에 있다고 지적한 사람은 아무도 없습니다.
Andy E

@AndyE는 아마 정규 표현식을 본 후에 TL; DR 모드로 들어가서 다른 답을 찾는다;)
BitTickler

11

이것은 "세계에서 가장 추악한 해킹"의 범주로 가야하지만 여기 있습니다.

먼저 현재 의 이름을 인쇄 함수 것은 (다른 답변에서와 같이) 나에게 제한적 인 것처럼 보입니다. 기능이 무엇인지 이미 알고 있기 때문입니다!

그러나 호출 함수 의 이름을 찾는 것은 추적 함수에 매우 유용 할 수 있습니다. 이것은 정규 표현식을 사용하지만 indexOf를 사용하면 약 3 배 빠릅니다.

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

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

me();

멋진 솔루션이지만 FYI Function # caller는 비표준 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Max Heiber

해당 함수가 데이터베이스에서 동적으로 작성되고 함수 이름에 키가 지정된 함수 내부의 컨텍스트 정보가 필요한 경우 현재 함수의 이름을 아는 것이 필수적 일 수 있습니다.
Paul Chernoch

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

});

세 번째 테스트는 테스트가 / util / functions에있는 경우에만 작동합니다.


7

getMyName아래 스 니펫 의 함수는 호출 함수의 이름을 반환합니다. 그것은 해킹이며 비표준 기능 에 의존 합니다 : 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있다 비표준 및 엄격한 모드에서 사용할 수 없습니다 .


함수에서 위치를 표시하고 익명 함수를 지원하도록 확장하십시오. ?))? $ / g, '$ 1 ($ 2 : $ 3)')
kofifus

엄격 모드에서는 Function.prototype.caller도 사용할 수 없습니다.
fijiaaron

1
화살표 기능, 저평가 답변에도 완벽하게 작동
Hao Wu

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

여기서 장점은 디스패처를 쉽게 재사용 할 수 있고 디스패치 큐를 인수로 수신 할 필요가 없으며 대신 호출 이름으로 암시됩니다.

결국 여기에 제시된 일반적인 경우는 "함수 이름을 인수로 사용하여 명시 적으로 전달할 필요가 없습니다"이며, jquery animate () 선택적 콜백과 같은 많은 경우에 유용 할 수 있습니다. 또는 타임 아웃 / 간격 콜백에서 (즉, 함수 NAME 만 전달).


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
오류 처리기에서 작업 중이며 호출 함수를보고하고 싶습니다.
sprugman 2016 년

1

내가 본 몇 가지 반응의 조합. (FF, Chrome, IE11에서 테스트)

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

randomFunction ()을 호출하면 함수 이름이 포함 된 문자열을 경고합니다.

JS 피들 데모 : http://jsfiddle.net/mjgqfhbe/



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

NodeJS의 결과

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

Firefox에서는 작동하지 않습니다. IE와 Edge에서 테스트되지 않았습니다.


함수 표현식의 결과

NodeJS의 결과

> 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

Firefox, Opera에서는 작동하지 않습니다. IE와 Edge에서 테스트되지 않았습니다.

노트:

  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

Igor Ostroumov의 변종 답변 .

매개 변수의 기본값으로 사용하려면 'caller'에 대한 두 번째 레벨 호출을 고려해야합니다.

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
"nom"은 프랑스어로 "name"입니다. 이러한 종류의 세부 사항은 언어 버전의 브라우저간에 변경됩니까? 나는 그렇게 생각하지 않을 것입니다.
argyle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.