Ответы:
В 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 - получить имя текущей функции .
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
а не имя вызывающего абонента.
По данным МДН
Предупреждение: 5-я редакция ECMAScript (ES5) запрещает использование arguments.callee () в строгом режиме. Избегайте использования arguments.callee (), указав для выражений функций имя или используйте объявление функции, где функция должна вызывать себя.
Как уже отмечалось, это применимо, только если ваш скрипт использует «строгий режим». Это в основном по соображениям безопасности, и, к сожалению, в настоящее время альтернативы этому нет.
Это должно сделать это:
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);
});
});
Обратите внимание, что третий тест будет работать, только если тест находится в / 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
не допускается в строгом режиме и Function.prototype.caller
является нестандартным и не допускается в строгом режиме .
Другим вариантом использования может быть диспетчер событий, связанный во время выполнения:
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 лет, так как этот вопрос был задан.
Теперь, не будучи профессиональным веб-разработчиком, который знает обо всех историях всех браузеров, когда-либо существовавших, вот как это работает для меня в браузере Chrome 2019 года:
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
Некоторые из других ответов натолкнулись на некоторые хромированные ошибки о строгом коде JavaScript и еще много чего.
Поскольку вы написали функцию с именем 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
Результат в Chrome
(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
Результат в Chrome
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
(function f() {
console.log(f.name); //logs f
})();
Вариант машинописного текста:
function f1() {}
function f2(f:Function) {
console.log(f.name);
}
f2(f1); //Logs f1
Примечание доступно только в двигателях, соответствующих ES6 / ES2015. Для более см.
Вот один вкладыш:
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.');
}
Это вариант Игоря Остроумова ответа :
Если вы хотите использовать его в качестве значения по умолчанию для параметра, вам необходимо рассмотреть вызов второго уровня к вызывающей стороне:
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();
}