Yanıtlar:
ES5 ve üzeri sürümlerde, bu bilgilere erişim yoktur.
JS'nin eski sürümlerinde bunu kullanarak alabilirsiniz arguments.callee
.
Muhtemelen ekstra önemsiz içereceği için adı ayrıştırmanız gerekebilir. Yine de, bazı uygulamalarda kullanarak adı alabilirsiniz arguments.callee.name
.
Ayrıştırma:
function DisplayMyName()
{
var myName = arguments.callee.toString();
myName = myName.substr('function '.length);
myName = myName.substr(0, myName.indexOf('('));
alert(myName);
}
Kaynak: Javascript - geçerli işlev adını al .
arguments.callee
katı modda izin verilmemesidir.
Anonim olmayan işlevler için
function foo()
{
alert(arguments.callee.name)
}
Ancak bir hata işleyici durumunda sonuç, hata işleyici işlevinin adı olur, değil mi?
İhtiyacınız olan her şey basit. Oluşturma işlevi:
function getFuncName() {
return getFuncName.caller.name
}
Bundan sonra, ihtiyacınız olduğunda, şunları kullanırsınız:
function foo() {
console.log(getFuncName())
}
foo()
// Logs: "foo"
function getFuncName() { return getFuncName.name }
getFuncName
arayanın adından ziyade adını alıyorsunuz .
MDN'ye göre
Uyarı: ECMAScript'in (ES5) 5. sürümü, arguments.callee () işlevinin katı modda kullanılmasını yasaklar. İşlev ifadelerine bir ad vererek arguments.callee () yöntemini kullanmaktan kaçının veya bir işlevin kendisini çağırması gereken bir işlev bildirimi kullanın.
Belirtildiği gibi bu sadece betiğiniz "katı mod" kullanıyorsa geçerlidir . Bu esas olarak güvenlik nedenlerinden ötürü ve ne yazık ki şu anda bunun bir alternatifi yok.
Bunu yapmalı:
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);
Arayan için sadece kullanın caller.toString()
.
[
Bu "dünyanın en çirkin hackleri" kategorisine girmeli, ama işte gidiyorsunuz.
Öncelikle, mevcut işlevin adını yazdırmak (diğer yanıtlarda olduğu gibi) benim için sınırlı bir kullanım alanına sahip gibi görünüyor, çünkü işlevin ne olduğunu zaten biliyorsunuz!
Ancak, çağıran işlevin adını bulmak bir izleme işlevi için oldukça yararlı olabilir. Bu normal ifade ile, ancak indexOf kullanmak yaklaşık 3 kat daha hızlı olurdu:
function getFunctionName() {
var re = /function (.*?)\(/
var s = getFunctionName.caller.toString();
var m = re.exec( s )
return m[1];
}
function me() {
console.log( getFunctionName() );
}
me();
İşte işe yarayacak bir yol:
export function getFunctionCallerName (){
// gets the text between whitespace for second part of stacktrace
return (new Error()).stack.match(/at (\S+)/g)[1].slice(3);
}
Sonra testlerinizde:
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);
});
});
Üçüncü testin yalnızca test / util / function konumunda bulunuyorsa çalışacağını unutmayın.
Aşağıdaki getMyName
snippet'teki işlev, çağıran işlevin adını döndürür. Bu kesmek ve güvenir standart dışı özellik: Error.prototype.stack
. Tarafından döndürülen dizenin biçiminin Error.prototype.stack
farklı motorlarda farklı şekilde uygulandığını unutmayın, bu muhtemelen her yerde çalışmaz:
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())
Başka çözümler hakkında: arguments.callee
katı modda izin verilmez ve Function.prototype.caller
bir standart dışı ve sıkı modda izin verilmez .
Başka bir kullanım durumu, çalışma zamanında bağlı bir olay dağıtıcısı olabilir:
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);
Buradaki avantaj, dağıtım programının kolayca yeniden kullanılabilmesi ve dağıtım sırasını bağımsız değişken olarak alması gerekmemesidir, bunun yerine çağrı adı ile örtülü olarak gelir ...
Sonunda, burada sunulan genel durum "işlev adını bir argüman olarak kullanmaktır, bu yüzden açıkça iletmeniz gerekmez" ve bu, jquery animate () isteğe bağlı geri çağırma, veya zaman aşımı / aralıklarla geri aramalarda (yani yalnızca bir NAME işlevi iletirsiniz).
Mevcut fonksiyonun adı ve nasıl elde edilebileceği, bu sorunun sorulduğu için son 10 yılda değişmiş gibi görünüyor.
Şimdiye kadar var olan tüm tarayıcıların tüm geçmişlerini bilen profesyonel bir web geliştiricisi olmak değil, 2019 chrome tarayıcısında benim için şu şekilde çalışıyor:
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
Diğer cevaplardan bazıları, sıkı javascript kodu ve ne olursa olsun bazı krom hataları ile karşılaştı.
Adında bir işlev yazdığınızdan foo
ve bunun myfile.js
neden olduğunu bildiğinizden, bu bilgileri neden dinamik olarak almanız gerekiyor?
arguments.callee.toString()
İşlev içinde kullanabilirsiniz (bu, tüm işlevin dize temsilidir) ve işlev adının değerini yeniden düzenleyebilirsiniz.
İşte kendi adını söyleyecek bir fonksiyon:
function foo() {
re = /^function\s+([^(]+)/
alert(re.exec(arguments.callee.toString())[1]);
}
Burada gördüğüm birkaç yanıtın bir kombinasyonu. (FF, Chrome, IE11'de test edilmiştir)
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 () çağrıldığında işlev adını içeren bir dize uyarılır.
JS Fiddle Demosu: http://jsfiddle.net/mjgqfhbe/
Bunun güncellenmiş bir cevabını şu cevapta bulabilirsiniz: https://stackoverflow.com/a/2161470/632495
ve tıklamak istemiyorsanız:
function test() {
var z = arguments.callee.name;
console.log(z);
}
Bilgiler 2016 yılında geçerlidir.
Opera'da Sonuç
>>> (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'da sonuç
(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
Düğümde Sonuç
> (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'ta çalışmıyor. IE ve Edge üzerinde test edilmedi.
Düğümde Sonuç
> var func11 = function(){
... console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11
Chrome'da sonuç
var func11 = function(){
console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11
Firefox, Opera'da çalışmıyor. IE ve Edge üzerinde test edilmedi.
Notlar:
~ $ 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
})();
Yazı tipi varyasyonu:
function f1() {}
function f2(f:Function) {
console.log(f.name);
}
f2(f1); //Logs f1
Yalnızca ES6 / ES2015 uyumlu motorlarda mevcuttur. Daha fazla bilgi için
İşte bir astar:
arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')
Bunun gibi:
function logChanges() {
let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
console.log(whoami + ': just getting started.');
}
Bu Igor Ostroumov'un cevabının bir çeşidi :
Bir parametre için varsayılan değer olarak kullanmak isterseniz, 'arayan' için ikinci düzey bir çağrı düşünmeniz gerekir:
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
Bu, dinamik olarak birden fazla işlevde yeniden kullanılabilir bir uygulamaya izin verecektir.
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
function bar(myFunctionName = getFunctionsNameThatCalledThisFunction())
{
alert(myFunctionName);
}
// pops-up "foo"
function foo()
{
bar();
}
function crow()
{
bar();
}
foo();
crow();
Dosya adını da istiyorsanız, başka bir soruda F-3000'in cevabını kullanan bu çözüm :
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();
}