source

해당 함수 내에서 함수 이름을 얻는 방법은 무엇입니까?

factcode 2022. 9. 24. 09:55
반응형

해당 함수 내에서 함수 이름을 얻는 방법은 무엇입니까?

그 기능 내부에서 기능명에 접속하려면 어떻게 해야 하나요?

// parasitic inheritance
var ns.parent.child = function() {
  var parent = new ns.parent();
  parent.newFunc = function() {

  }
  return parent;
}

var ns.parent = function() {
  // at this point, i want to know who the child is that called the parent
  // ie
}

var obj = new ns.parent.child();

ES6를 사용하면 .myFunction.name.

참고: 일부 JS 미니어는 더 잘 압축하기 위해 함수 이름을 버릴있습니다. 이를 방지하려면 설정을 조정해야 할 수 있습니다.

ES5에서 가장 좋은 방법은 다음과 같습니다.

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

「」를 사용합니다.Function.caller표준입입니니다Function.caller ★★★★★★★★★★★★★★★★★」arguments.callee엄하다

편집: 아래 nus의 regex 기반 답변도 동일한 결과를 얻었지만 성능이 더 우수합니다!

ES6(아래 Sendy Halim의 답변에서 영감을 얻음):

myFunction.name

MDN에 대한 설명. 2015년 현재 IE를 제외한 모든 주요 브라우저 및 nodej에서 작동합니다.

에서는 "이러한 함수는: "이러한 함수는 없습니다."가.bound <originalName>를 제거해야 . 원래 이름을 얻으려면 "바운드"를 삭제해야 합니다.


ES5(Vlad의 답변에서 영감을 얻음):

함수에 대한 참조가 있는 경우 다음을 수행할 수 있습니다.

function functionName( func )
{
    // Match:
    // - ^          the beginning of the string
    // - function   the word 'function'
    // - \s+        at least some white space
    // - ([\w\$]+)  capture one or more valid JavaScript identifier characters
    // - \s*        optionally followed by white space (in theory there won't be any here,
    //              so if performance is an issue this can be omitted[1]
    // - \(         followed by an opening brace
    //
    var result = /^function\s+([\w\$]+)\s*\(/.exec( func.toString() )

    return  result  ?  result[ 1 ]  :  '' // for an anonymous function there won't be a match
}
  • 유닛 테스트를 실행하거나 구현의 차이를 검증한 적은 없지만 코멘트를 남기지 않더라도 원칙적으로 동작합니다.
  • 참고: 바인딩된 함수에서는 작동하지 않습니다.
  • ★★★★★★caller ★★★★★★★★★★★★★★★★★」callee권장되지 않는 것으로 간주됩니다.

[1] 이것은 합법적이고 구문 강조 표시 도구가 함수 이름과 괄호 사이의 공백을 고려하지 않는 경우가 많기 때문에 여기에 포함시킵니다.한편, 여기에 공백이 포함되는 .toString()의 실장은 알 수 없기 때문에 생략할 수 있습니다.


첫 번째 질문에 대한 답변으로 기생적인 상속을 중단하고 좀 더 전통적인 OOP 디자인 패턴을 선택하겠습니다.는 TidBits를 썼다.OoJs는 C++를 모방한 피처 세트를 사용하여 OOP 코드를 JavaScript로 편안하게 작성한다(아직 완성되지는 않았지만 대부분).

, 전달을 을 알 수 .parent★★★★★, 패턴은,은, 하고 이라고 생각되기 때문입니다.하지만 기존의 디자인 패턴은 당신을 그것으로부터 구해주지 않을 것입니다. 왜냐하면 일반적으로 당신의 의존성을 분명히 하고 강요하는 것은 좋은 것으로 여겨지기 때문입니다.

나는 또한 익명의 행사들을 멀리할 것을 제안하고 싶다.PITA의 디버깅과 프로파일링을 하는 것은 모든 것이 "익명의 함수"로 표시되기 때문이며, 제가 아는 한 그들에게 이득은 없습니다.

이름 없는 함수를 변수에 할당하는 것입니다.이름 있는 함수식이 필요할 수 있습니다(http://kangax.github.com/nfe/ ).

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

하지만 크로스 브라우저가 어느 정도인지 모르겠습니다.IE6에서는arguments. arguments.callee를 사용하는 경우 합니다.strict mode.

내 인생에서 가장 멍청한 글처럼 보이지만, 재미있어요.d

function getName(d){
  const error = new Error();
  const firefoxMatch = (error.stack.split('\n')[0 + d].match(/^.*(?=@)/) || [])[0];
  const chromeMatch = ((((error.stack.split('at ') || [])[1 + d] || '').match(/(^|\.| <| )(.*[^(<])( \()/) || [])[2] || '').split('.').pop();
  const safariMatch = error.stack.split('\n')[0 + d];

  // firefoxMatch ? console.log('firefoxMatch', firefoxMatch) : void 0;
  // chromeMatch ? console.log('chromeMatch', chromeMatch) : void 0;
  // safariMatch ? console.log('safariMatch', safariMatch) : void 0;
  
  return firefoxMatch || chromeMatch || safariMatch;
}

d - 스택 깊이0이이름을 돌려줍니다. - 이 함수의 이름을 .1 - 부모 등
[0 + d]하기 위해서 - 이 일어나는지 - 이해하려고 - 이해하려고 - 이해하려고
firefoxMatch mac의 피우고 에 테스트에 남았습니다. - (- : : 、 mac 、 mac ) 。

테스트:

function limbo(){
  for(let i = 0; i < 4; i++){
    console.log(getName(i));
  }
}
function lust(){
  limbo();
}
function gluttony(){
  lust();
}

gluttony();

결과:
크롬:
여기에 이미지 설명 입력

Fitefox:
여기에 이미지 설명 입력

이 솔루션은 단지 재미로 만든 것입니다!실제 프로젝트에는 사용하지 마십시오.ES 사양에 의존하지 않고 브라우저 실현에만 의존합니다.다음 번에 Chrome/firefox/safari 업데이트 후 파손될 수 있습니다.
, ha)이 경우, 에러(ha) 처리가 .d합니다.오류가 표시됩니다.
오류 패턴의 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >> > >
ES6 ( ( (((((((((().split('.').pop()할 수 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다.

의 ★★★★constructor을 폭로하다name함수 이름입니다.하면 됩니다.constructor(「」를 사용)new 또 )prototype:

function Person() {
  console.log(this.constructor.name); //Person
}

var p = new Person();
console.log(p.constructor.name); //Person

console.log(Person.prototype.constructor.name);  //Person

다음과 같이 하면 도움이 될 수 있습니다.

function foo() { bar(); }

function bar() { console.log(bar.caller.name); }

foo()를 실행하면 익명함수에서 호출한 경우 "foo" 또는 정의되지 않은 상태가 출력됩니다.

이것은 컨스트럭터에서도 동작합니다.이 경우 호출된 컨스트럭터의 이름(예: "Foo")을 출력합니다.

자세한 내용은 이쪽:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller

비표준이지만 모든 주요 브라우저에서 지원된다고 주장합니다.Firefox, Safari, Chrome, Opera 및 IE.

그럴수는 없어요.함수에는 표준에 따른 이름이 없습니다(Mozilla에는 이러한 속성이 있지만). 함수는 이름이 있는 변수에만 할당할 수 있습니다.

또, 코멘트:

// access fully qualified name (ie "my.namespace.myFunc")

my.204.m 함수의 내부에 있습니다.yFunc.getFn

new에 의해 생성된 객체의 생성자를 반환할 수 있습니다.

그래서 당신은 말할 수 있다.

var obj = new my.namespace.myFunc();
console.info(obj.constructor); //my.namespace.myFunc

Error.stack을 지원하는 브라우저(전부는 아닐 수 있음)에 사용할 수 있습니다.

function WriteSomeShitOut(){ 
  var a = new Error().stack.match(/at (.*?) /);
  console.log(a[1]);
} 
WriteSomeShitOut();

물론 이것은 현재의 기능을 위한 것이지만, 이해하실 수 있습니다.

코드하는 동안 침 흘리는 행복한 모습

다음을 사용할 수 있습니다.

JavaScript의 대부분의 구현에서는 컨스트럭터의 참조가 범위 내에 있으면 그 이름 속성(Function.name 또는 Object.constructor.name)에서 문자열 이름을 얻을 수 있습니다.

다음을 사용할 수 있습니다.

원어민arguments.caller메서드는 권장되지 않지만 대부분의 브라우저는Function.caller는 실제 호출 객체(코드 본문)를 반환합니다.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fcaller

소스 맵을 작성할 수 있습니다.

오브젝트 자체가 아닌 리터럴 함수 시그니처(그 "이름")가 필요한 경우 자주 액세스해야 하는 API 문자열 값의 배열 참조를 작성하는 등 조금 더 커스터마이즈된 것에 의존해야 할 수 있습니다.를 사용하여 매핑할 수 있습니다.Object.keys()하겠습니다.

하시면 됩니다.name하지 않는 한 이름을

예를 들어 다음과 같습니다.

var Person = function Person () {
  this.someMethod = function () {};
};

Person.prototype.getSomeMethodName = function () {
  return this.someMethod.name;
};

var p = new Person();
// will return "", because someMethod is assigned with anonymous function
console.log(p.getSomeMethodName());

이제 명명된 함수를 사용해 보겠습니다.

var Person = function Person () {
  this.someMethod = function someMethod() {};
};

이제 사용할 수 있습니다.

// will return "someMethod"
p.getSomeMethodName()

다음과 같이 생성자 이름을 사용할 수 있습니다.

{your_function}.prototype.constructor.name

이 코드는 단순히 메서드의 이름을 반환합니다.

ECMAScript 6의 일부로 Function.name 메서드를 사용할 수 있습니다.

function doSomething() {}

alert(doSomething.name); // alerts "doSomething"

오래된 질문인 것은 알지만 최근 디버깅을 위해 React Component의 메서드를 꾸미려다 비슷한 문제가 발생했습니다. 말했지만, 까도 as as as as as as as as 。arguments.caller ★★★★★★★★★★★★★★★★★」arguments.callee는 React 트랜스파일링에서 기본적으로 활성화되어 있는 strict 모드에서는 금지되어 있습니다.비활성화할 수도 있고 다른 해킹을 생각해 낼 수도 있습니다. React에서는 모든 클래스 함수가 명명되어 있기 때문에 실제로 다음과 같은 작업을 실제로 수행할 수 있습니다.

Component.prototype.componentWillMount = function componentWillMount() {
    console.log('Callee name: ', this.__proto__.constructor.toString().substr(0,30));
...
}

이건 나한테 효과가 있었어.

function AbstractDomainClass() {
    this.className = function() {
        if (!this.$className) {
            var className = this.constructor.toString();
            className = className.substr('function '.length);
            className = className.substr(0, className.indexOf('('));
            this.$className = className;
        }
        return this.$className;
    }
}

테스트 코드:

var obj = new AbstractDomainClass();
expect(obj.className()).toBe('AbstractDomainClass');

저도 비슷한 문제가 있어서 다음과 같이 해결했습니다.

Function.prototype.myname = function() {
   return this.toString()
       .substr( 0, this.toString().indexOf( "(" ) )
       .replace( "function ", "" ); 
}

이 코드는 이 토론의 선두에서 이미 읽은 하나의 답변을 보다 편안하게 구현합니다.이제 함수 객체의 이름을 검색하는 멤버 함수가 있습니다.여기 전체 대본이 있습니다.

<script language="javascript" TYPE="text/javascript">

    Function.prototype.myname = function() { 
        return this.toString()
            .substr( 0, this.toString().indexOf( "(" ) )
            .replace("function ", "" ); 
    }
    function call_this( _fn ) { document.write( _fn.myname() ); }
    function _yeaaahhh() { /* do something */ }
    call_this( _yeaaahhh ); 

</script>

당신이 원하는 것을 이해했다면 함수 생성자 안에서 하는 일입니다.

if (!(this instanceof arguments.callee)) {
    throw "ReferenceError: " + arguments.callee.name + " is not defined";
}

이것은 ES5, ES6, 모든 브라우저 및 strict 모드 기능에서 작동합니다.

이름 붙여진 함수는 다음과 같습니다.

(function myName() {
  console.log(new Error().stack.split(/\r\n|\r|\n/g)[1].trim());
})();
at myName (<anonymous>:2:15)

익명의 함수는 다음과 같습니다.

(() => {
  console.log(new Error().stack.split(/\r\n|\r|\n/g)[1].trim());
})();
at <anonymous>:2:15

[매직 변수와 같은] 함수 이름을 동적으로 검색하는 간단한 솔루션은 범위 변수를 사용하는 것입니다.

{
  function parent() {
    console.log(a.name);
  }; let a = parent
}
{
  function child() {
    console.log(a.name)
  }; let a = child
};

parent();//logs parent
child();//logs child

주의: 중첩된 함수는 소스 요소가 아니므로 중단되지 않습니다.또한 이 기술은 익명 함수와 함께 사용할 수 없습니다.

여기를 봐주세요.http://www.tek-tips.com/viewthread.cfm?qid=1209619

arguments.callee.toString();

니즈에 맞는 것 같아.

실행 중인 기능 내에서 기능 이름을 쉽게 얻을 수 있습니다.

function x(){alert(this.name)};x()

Error.stack을 사용하여 함수 이름과 현재 위치의 정확한 위치를 추적할 수 있습니다.

스택 트레이스를 참조해 주세요.js

언급URL : https://stackoverflow.com/questions/2648293/how-to-get-the-function-name-from-within-that-function

반응형