Jak mogę uzyskać dostęp do nazwy funkcji z wnętrza tej funkcji?
// parasitic inheritance
var ns.parent.child = function() {
var parent = new ns.parent();
parent.newFunc = function() {
}
return parent;
}
var ns.parent = function() {
// at this point, i want to know who the child is that called the parent
// ie
}
var obj = new ns.parent.child();
javascript
function
Scott Klarenbach
źródło
źródło
Odpowiedzi:
W ES5 najlepiej jest:
Używanie
Function.caller
jest niestandardowe.Function.caller
iarguments.callee
oba są zabronione w trybie ścisłym.Edycja: poniższa odpowiedź wyrażenia regularnego nus osiąga to samo, ale ma lepszą wydajność!
W ES6 możesz po prostu użyć
myFunction.name
.Uwaga: Uwaga: niektóre minizatory JS mogą wyrzucać nazwy funkcji, aby lepiej się kompresować; może być konieczne dostosowanie ich ustawień, aby tego uniknąć.
źródło
fun.toString().substr(0, 100)
co dla moich potrzeb wystarczy, aby zlokalizować daną funkcję. Dzięki za inspirację!myFunction.name
najlepiej robić w ES6.myFunction.name
wpisywać nazwę funkcji? pokonuje cel magicznych zmiennych.arr[index].name
też zadziała :)myFunction.name
również zostanie zaktualizowany. Jasne, intelliJ obsługuje zmianę nazw identyfikatorów w łańcuchach, ale działa to o wiele mniej konsekwentnie i po cichu stanie się przestarzałe, jeśli ktoś zapomni zaznaczyć opcję „szukaj w łańcuchach”.myFunction.name
jest nieco lepszym wyborem niż kodowanie łańcucha na stałe.ES6 (zainspirowany odpowiedzią sendy halim poniżej):
Objaśnienie dotyczące MDN . Od 2015 roku działa w nodejs i wszystkich głównych przeglądarkach oprócz IE.
Uwaga: W przypadku funkcji związanych daje to „
bound <originalName>
”. Będziesz musiał usunąć „związany”, jeśli chcesz uzyskać oryginalną nazwę.ES5 (zainspirowany odpowiedzią Vlada):
Jeśli masz odwołanie do funkcji, możesz:
caller
icallee
są uważane za przestarzałe.[1] Zamieszczam to tutaj, ponieważ jest to legalne i często wystarczające narzędzia do podświetlania składni nie uwzględniają białych znaków między nazwą funkcji a nawiasami. Z drugiej strony nie znam żadnej implementacji .toString (), która zawierałaby tutaj białe znaki, dlatego możesz to pominąć.
W odpowiedzi na pierwotne pytanie porzuciłbym pasożytnicze dziedzictwo i wybrałem bardziej tradycyjne wzorce projektowania OOP. Napisałem TidBits.OoJs, aby wygodnie pisać kod OOP w JavaScript z zestawem funkcji naśladujących C ++ (jeszcze nie ukończony, ale głównie).
Z komentarzy wynika, że chciałbyś uniknąć przekazywania informacji
parent
konstruktorowi. Muszę przyznać, że tradycyjne wzorce projektowe nie uchronią cię przed tym, ponieważ generalnie dobrze jest uwidocznić i narzucić swoje zależności.Sugerowałbym również odejście od anonimowych funkcji. Sprawiają, że debugowanie i profilowanie jest PITA, ponieważ wszystko pojawia się jako „anonimowa funkcja” i nie mam dla nich żadnych korzyści, o których jestem świadomy.
źródło
.name
właściwość metody komponentu była wyświetlana jako ciąg „wartość”, bez względu na to, jak się nazywała. Co dziwne, podczas testowania w aplikacji expo wszystko było w porządku, jednak po skompilowaniu w prawdziwą aplikację ulegałoby awarii po cichu.to, co robisz, to przypisywanie zmiennej bez nazwy do zmiennej. prawdopodobnie potrzebujesz zamiast tego nazwanego wyrażenia funkcyjnego ( http://kangax.github.com/nfe/ ).
jednak nie jestem pewien, ile to kosztuje przeglądarka; występuje problem z IE6, który powoduje wyciek nazwy funkcji do zakresu zewnętrznego. również arguments.callee jest trochę przestarzały i spowoduje błąd, jeśli go używasz
strict mode
.źródło
Każda
constructor
ujawnia właściwośćname
, która jest nazwą funkcji. Uzyskujesz dostęp zaconstructor
pośrednictwem instancji (za pomocąnew
) lubprototype
:źródło
console.log
dzienniki połączeńwindow
lubObject
dla mnie, w zależności od tego, gdzie je uruchamiam, niePerson
.To wygląda jak najgłupsza rzecz, którą napisałem w życiu, ale to zabawne: D
d
- głębokość stosu.0
- zwróć nazwę tej funkcji,1
- rodzic, itp .;[0 + d]
- tylko dla zrozumienia - co się dzieje;firefoxMatch
- działa na safari, ale naprawdę miałem trochę czasu na testy, ponieważ właściciel Maca wrócił po paleniu i odwiózł mnie: ”(Testowanie:
Wynik:
Chrome:
Fitefox:
To rozwiązanie było tworzone tylko dla zabawy ! Nie używaj go do prawdziwych projektów. Nie zależy to od specyfikacji ES, zależy tylko od realizacji przeglądarki. Po następnej aktualizacji chrome / firefox / safari może zostać uszkodzony.
Co więcej, nie ma przetwarzania błędów (ha) - jeśli
d
będzie większa niż długość stosu - pojawi się błąd;W przypadku innych wrowsers wzorzec komunikatów o błędach - otrzymasz błąd;
Musi działać dla klas ES6 (
.split('.').pop()
), ale możesz dostać błąd;źródło
To może Ci pomóc:
uruchomienie foo () spowoduje wyświetlenie „foo” lub niezdefiniowane, jeśli wywołasz z funkcji anonimowej.
Działa również z konstruktorami, w którym to przypadku wyświetli nazwę wywołującego konstruktora (np. „Foo”).
Więcej informacji tutaj: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller
Twierdzą, że jest niestandardowy, ale obsługuje również wszystkie główne przeglądarki: Firefox, Safari, Chrome, Opera i IE.
źródło
Nie możesz Funkcje nie mają nazw zgodnie ze standardem (chociaż mozilla ma taki atrybut) - można je przypisać tylko do zmiennych o nazwach.
Również twój komentarz:
jest w funkcji my.namespace.myFunc.getFn
Co możesz zrobić, to zwrócić konstruktor obiektu utworzonego przez new
Więc możesz powiedzieć
źródło
Możesz tego użyć w przeglądarkach obsługujących Error.stack (prawdopodobnie nie wszystkie)
Oczywiście dotyczy to bieżącej funkcji, ale masz pomysł.
szczęśliwy ślinienie podczas pisania
źródło
Możesz użyć
name
właściwości, aby uzyskać nazwę funkcji, chyba że używasz funkcji anonimowejNa przykład:
teraz spróbujmy z nazwaną funkcją
teraz możesz użyć
źródło
Możesz użyć nazwy konstruktora, takiej jak:
ten kod po prostu zwraca nazwę metody.
źródło
jako część, jak
ECMAScript 6
można użyć metody Function.nameźródło
Możesz użyć
Function.name
:W większości implementacji JavaScript, gdy masz zasięg konstruktora w zakresie, możesz uzyskać jego nazwę ciągu z jego właściwości name (np. Function.name lub Object.constructor.name
Możesz użyć
Function.callee
:Metoda natywna
arguments.caller
jest przestarzała, ale większość przeglądarek obsługuje tę funkcjęFunction.caller
, która zwróci rzeczywisty obiekt wywołujący (jego treść): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ Funkcja / osoba dzwoniąca? Redirectlocale = en-US & redirectslug = JavaScript% 2FReference% 2FGlobal_Objects% 2FFunction% 2FcallerMożesz utworzyć mapę źródłową :
Jeśli potrzebna jest dosłowna sygnatura funkcji (jej „nazwa”), a nie sam obiekt, być może trzeba będzie zastosować coś nieco bardziej dostosowanego, na przykład utworzyć odwołanie do tablicy wartości parametrów API, które trzeba będzie dostęp często. Możesz zmapować je razem za pomocą
Object.keys()
i swojej tablicy ciągów lub zajrzeć do biblioteki map źródłowych Mozilli na GitHub, w przypadku większych projektów: https://github.com/mozilla/source-mapźródło
Wiem, że to stare pytanie, ale ostatnio miałem do czynienia z podobnym problemem podczas próby udekorowania niektórych metod React Component do celów debugowania. Jak ludzie już mówili
arguments.caller
iarguments.callee
są zabronione w trybie ścisłym, który prawdopodobnie jest domyślnie włączony w transpilacji React. Możesz to wyłączyć albo mogłem wymyślić inny hack, ponieważ w React wszystkie funkcje klas są nazwane, możesz to zrobić:źródło
To zadziałało dla mnie.
Kod testowy:
źródło
Miałem podobny problem i rozwiązałem go w następujący sposób:
Ten kod implementuje, w bardziej komfortowy sposób, jedną odpowiedź, którą już przeczytałem tutaj na początku tej dyskusji. Teraz mam funkcję członka pobierającą nazwę dowolnego obiektu funkcji. Oto pełny skrypt ...
źródło
Jeśli zrozumiałem, co chcesz zrobić, to robię to w konstruktorze funkcji.
źródło
Działa to w ES5, ES6, wszystkich przeglądarkach i funkcjach trybu ścisłego.
Oto jak to wygląda z nazwaną funkcją.
Oto jak to wygląda z anonimową funkcją.
źródło
at myName (<anonymous>:2:15)
Firefox:@debugger eval code:3:3
spójrz tutaj: http://www.tek-tips.com/viewthread.cfm?qid=1209619
wydaje się być odpowiedni do twoich potrzeb.
źródło
możesz użyć Error.stack do śledzenia nazwy funkcji i dokładnej pozycji, w której się znajdujesz.
Zobacz plik stacktrace.js
źródło
Łatwy sposób na uzyskanie nazwy funkcji z uruchomionej funkcji.
źródło
this
zasadzie może być wszystko. spróbuj(function(){console.log(this.name);}).bind({name: "put basically anything here even an object maybe a 1TB string maybe a class definition"})()