Відповіді:
У версії 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
а не ім’я його абонента.
За даними MDN
Попередження: 5-е видання ECMAScript (ES5) забороняє використовувати argument.callee () в суворому режимі. Уникайте використання argument.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 / функцій
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 (), або у зворотному режимі викликів / інтервалів (тобто ви передаєте лише NAME).
Назва поточної функції та те, як її можна отримати, схоже, змінилися за останні 10 років, оскільки це питання було задано.
Тепер, не будучи професійним веб-розробником, який знає про всі історії всіх браузерів, які коли-небудь існували, ось як це працює для мене в хромованому браузері 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();
}