Jawaban:
Di ES5 dan di atasnya, tidak ada akses ke informasi itu.
Di versi JS yang lebih lama, Anda bisa mendapatkannya dengan menggunakan arguments.callee
.
Anda mungkin harus menguraikan nama, karena mungkin akan menyertakan beberapa sampah tambahan. Padahal, dalam beberapa implementasi Anda hanya bisa mendapatkan nama menggunakan arguments.callee.name
.
Parsing:
function DisplayMyName()
{
var myName = arguments.callee.toString();
myName = myName.substr('function '.length);
myName = myName.substr(0, myName.indexOf('('));
alert(myName);
}
arguments.callee
adalah tidak diperbolehkan dalam mode ketat.
Untuk fungsi non-anonim
function foo()
{
alert(arguments.callee.name)
}
Tetapi dalam kasus penangan kesalahan hasilnya adalah nama fungsi penangan kesalahan, bukan?
Semua yang Anda butuhkan sederhana. Buat fungsi:
function getFuncName() {
return getFuncName.caller.name
}
Setelah itu kapan pun Anda butuhkan, Anda cukup menggunakan:
function foo() {
console.log(getFuncName())
}
foo()
// Logs: "foo"
function getFuncName() { return getFuncName.name }
getFuncName
daripada nama pemanggilnya.
Menurut MDN
Peringatan: ECMAScript (ES5) edisi ke-5 melarang penggunaan arguments.callee () dalam mode ketat. Hindari menggunakan arguments.callee () dengan memberikan ekspresi fungsi nama atau menggunakan deklarasi fungsi di mana fungsi harus memanggil dirinya sendiri.
Sebagaimana dicatat ini berlaku hanya jika skrip Anda menggunakan "mode ketat". Ini terutama karena alasan keamanan dan sayangnya saat ini tidak ada alternatif untuk ini.
Ini harus dilakukan:
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);
Untuk penelepon, gunakan saja caller.toString()
.
[
Ini harus masuk dalam kategori "peretasan terjelek di dunia", tapi begini saja.
Pertama-tama, mencetak nama fungsi saat ini (seperti pada jawaban lain) tampaknya memiliki penggunaan terbatas bagi saya, karena Anda semacam sudah tahu apa fungsinya!
Namun, mengetahui nama fungsi panggilan bisa sangat berguna untuk fungsi penelusuran. Ini dengan regexp, tetapi menggunakan indexOf sekitar 3x lebih cepat:
function getFunctionName() {
var re = /function (.*?)\(/
var s = getFunctionName.caller.toString();
var m = re.exec( s )
return m[1];
}
function me() {
console.log( getFunctionName() );
}
me();
Inilah cara yang akan berhasil:
export function getFunctionCallerName (){
// gets the text between whitespace for second part of stacktrace
return (new Error()).stack.match(/at (\S+)/g)[1].slice(3);
}
Kemudian dalam tes Anda:
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);
});
});
Perhatikan bahwa tes ketiga hanya akan berfungsi jika tes terletak di / util / functions
The getMyName
fungsi dalam potongan bawah kembali nama fungsi menelepon. Ini hack dan bergantung pada non-standar fitur: Error.prototype.stack
. Perhatikan bahwa format string yang dikembalikan oleh Error.prototype.stack
diimplementasikan secara berbeda di mesin yang berbeda, jadi ini mungkin tidak akan berfungsi di mana-mana:
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())
Tentang solusi lain: arguments.callee
tidak diperbolehkan dalam mode ketat dan Function.prototype.caller
merupakan non-standar dan tidak diperbolehkan dalam mode ketat .
Kasing penggunaan lain bisa berupa acara dispatcher yang terikat saat runtime:
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);
Keuntungannya di sini adalah operator dapat dengan mudah digunakan kembali dan tidak harus menerima antrian pengiriman sebagai argumen, alih-alih itu tersirat dengan nama doa ...
Pada akhirnya, kasus umum yang disajikan di sini adalah "menggunakan nama fungsi sebagai argumen sehingga Anda tidak harus meneruskannya secara eksplisit", dan itu bisa berguna dalam banyak kasus, seperti jquery animate () callback opsional, atau dalam callback timeout / interval, (yaitu Anda hanya melewati NAMA funcion).
Nama fungsi saat ini dan bagaimana hal itu dapat diperoleh tampaknya telah berubah selama 10 tahun terakhir, sejak pertanyaan ini diajukan.
Sekarang, bukan menjadi pengembang web pro yang tahu tentang semua sejarah semua browser yang pernah ada, di sini adalah cara kerjanya untuk saya di browser chrome 2019:
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
Beberapa jawaban lain mengalami beberapa kesalahan chrome tentang kode javascript yang ketat dan yang lainnya.
Karena Anda telah menulis fungsi bernama foo
dan Anda tahu itu myfile.js
mengapa Anda perlu mendapatkan informasi ini secara dinamis?
Bahwa menjadi kata Anda dapat menggunakan arguments.callee.toString()
di dalam fungsi (ini adalah representasi string dari seluruh fungsi) dan regex nilai dari nama fungsi.
Berikut adalah fungsi yang akan memunculkan namanya sendiri:
function foo() {
re = /^function\s+([^(]+)/
alert(re.exec(arguments.callee.toString())[1]);
}
Kombinasi dari beberapa tanggapan yang saya lihat di sini. (Diuji dalam 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);
}
Memanggil randomFunction () akan mengingatkan string yang berisi nama fungsi.
Demo JS Fiddle: http://jsfiddle.net/mjgqfhbe/
Jawaban yang diperbarui untuk ini dapat ditemukan di jawaban ini: https://stackoverflow.com/a/2161470/632495
dan, jika Anda tidak ingin mengklik:
function test() {
var z = arguments.callee.name;
console.log(z);
}
Informasi aktual pada tahun 2016 tahun.
Hasil di Opera
>>> (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
Menghasilkan 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
Menghasilkan 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
Tidak berfungsi di Firefox. Belum diuji pada IE dan Edge.
Menghasilkan NodeJS
> var func11 = function(){
... console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11
Menghasilkan Chrome
var func11 = function(){
console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11
Tidak berfungsi di Firefox, Opera. Belum diuji pada IE dan Edge.
Catatan:
~ $ 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
})();
Variasi naskah:
function f1() {}
function f2(f:Function) {
console.log(f.name);
}
f2(f1); //Logs f1
Catatan hanya tersedia di mesin yang sesuai dengan ES6 / ES2015. Untuk lebih banyak lihat
Ini satu liner:
arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')
Seperti ini:
function logChanges() {
let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
console.log(whoami + ': just getting started.');
}
Ini varian dari jawaban Igor Ostroumov :
Jika Anda ingin menggunakannya sebagai nilai default untuk suatu parameter, Anda perlu mempertimbangkan panggilan tingkat kedua ke 'pemanggil':
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
Ini secara dinamis akan memungkinkan implementasi yang dapat digunakan kembali dalam berbagai fungsi.
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
function bar(myFunctionName = getFunctionsNameThatCalledThisFunction())
{
alert(myFunctionName);
}
// pops-up "foo"
function foo()
{
bar();
}
function crow()
{
bar();
}
foo();
crow();
Jika Anda ingin nama file juga, berikut adalah solusi menggunakan jawaban dari F-3000 pada pertanyaan lain:
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();
}
Mencoba:
alert(arguments.callee.toString());