回答:
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);
}
arguments.callee
厳密モードでは許可されないことです。
非匿名関数の場合
function foo()
{
alert(arguments.callee.name)
}
しかし、エラーハンドラーの場合、結果はエラーハンドラー関数の名前になりますよね。
必要なものはすべてシンプルです。関数を作成します。
function getFuncName() {
return getFuncName.caller.name
}
その後、必要なときにいつでも使用できます。
function foo() {
console.log(getFuncName())
}
foo()
// Logs: "foo"
function getFuncName() { return getFuncName.name }
getFuncName
、呼び出し元の名前ではなく、名前が取得されます。
これはそれを行うはずです:
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);
発信者は、単にを使用しますcaller.toString()
。
[
これは「世界で最も醜いハック」の範疇に入りますが、ここに行きます。
まず、現在の名前を出力します関数の(他の回答のように)ことは、関数が何であるかをすでに知っているので、私には使用が制限されているようです!
ただし、呼び出し元の関数の名前を見つけることは、トレース関数にはかなり役立ちます。これは正規表現を使用していますが、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();
これが機能する方法です:
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);
});
});
3番目のテストは、テストが/ util / functionsにある場合にのみ機能することに注意してください。
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
strictモードでFunction.prototype.caller
は許可されておらず、非標準であり、strictモードでは許可されていません。
もう1つの使用例は、実行時にバインドされるイベントディスパッチャーです。
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()オプションのコールバックなど、多くの場合に役立ちます。またはタイムアウト/インターバルのコールバックで(つまり、関数名のみを渡します)。
現在の関数の名前とその取得方法は、この質問が出されてから過去10年間で変わったようです。
さて、これまで存在していたすべてのブラウザーのすべての履歴を知っているプロのWeb開発者ではなく、2019 Chromeブラウザーでの私にとっての動作は次のとおりです。
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
他の回答のいくつかは、厳密なJavaScriptコードなどに関するChromeエラーに遭遇しました。
という名前の関数を記述していて、そのため、この情報を動的に取得する必要foo
があるのはmyfile.js
なぜですか。
arguments.callee.toString()
関数内(これは関数全体の文字列表現です)で使用でき、関数名の値を正規表現できます。
以下は、独自の名前を吐き出す関数です。
function foo() {
re = /^function\s+([^(]+)/
alert(re.exec(arguments.callee.toString())[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 Fiddleデモ:http : //jsfiddle.net/mjgqfhbe/
これに対する更新された回答は、この回答で見つけることができます:https : //stackoverflow.com/a/2161470/632495
クリックしたくない場合は、
function test() {
var z = arguments.callee.name;
console.log(z);
}
情報は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でテストされていません。
ノート:
~ $ 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
ここにワンライナーがあります:
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.');
}
これはイゴールオストロウモフの変形です答えの:
これをパラメーターのデフォルト値として使用する場合は、「caller」の第2レベルの呼び出しを検討する必要があります。
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();
}