validacion tipos funciones formularios ejemplos con javascript function

javascript - tipos - ¿Cómo obtener el nombre de la función desde dentro de esa función?



tipos de funciones en javascript (18)

Como parte de ECMAScript 6 puede usar el método Function.name

function doSomething() {} alert(doSomething.name); // alerts "doSomething"

¿Cómo puedo acceder al nombre de una función desde dentro de esa función?

// 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();


Cualquier constructor expone un name propiedad, que es el nombre de la función. Se accede al constructor través de una instancia (usando new ) o un prototype :

function Person() { console.log(this.constructor.name); //Person } var p = new Person(); console.log(p.constructor.name); //Person console.log(Person.prototype.constructor.name); //Person


En ES5, lo mejor que puedes hacer es:

function functionName(fun) { var ret = fun.toString(); ret = ret.substr(''function ''.length); ret = ret.substr(0, ret.indexOf(''('')); return ret; }

El uso de Function.caller no es estándar. Function.caller y arguments.callee están prohibidos en modo estricto.

Edición: la respuesta a continuación de expresiones regulares de nus logra lo mismo, ¡pero tiene un mejor rendimiento!

En ES6, puedes usar myFunction.name .

Nota: Tenga en cuenta que algunos mineros JS pueden eliminar nombres de funciones para comprimir mejor; Es posible que tengas que modificar sus configuraciones para evitar eso.


Esto funcionó para mí.

function AbstractDomainClass() { this.className = function() { if (!this.$className) { var className = this.constructor.toString(); className = className.substr(''function ''.length); className = className.substr(0, className.indexOf(''('')); this.$className = className; } return this.$className; } }

Código de prueba:

var obj = new AbstractDomainClass(); expect(obj.className()).toBe(''AbstractDomainClass'');


Esto podría funcionar para usted:

function foo() { bar(); } function bar() { console.log(bar.caller.name); }

ejecutar foo () dará como resultado "foo" o indefinido si llama desde una función anónima.

También funciona con los constructores, en cuyo caso se emitirá el nombre del constructor que llama (por ejemplo, "Foo").

Más información aquí: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller

Afirman que no es estándar, pero también es compatible con todos los navegadores principales: Firefox, Safari, Chrome, Opera e IE.


Parece lo más estúpido que escribí en mi vida, pero es gracioso: D

function getName(d){ const error = new Error(); const firefoxMatch = (error.stack.split(''/n'')[0 + d].match(/^.*(?=@)/) || [])[0]; const chromeMatch = ((((error.stack.split(''at '') || [])[1 + d] || '''').match(/(^|/.| <| )(.*[^(<])( /()/) || [])[2] || '''').split(''.'').pop(); const safariMatch = error.stack.split(''/n'')[0 + d]; // firefoxMatch ? console.log(''firefoxMatch'', firefoxMatch) : void 0; // chromeMatch ? console.log(''chromeMatch'', chromeMatch) : void 0; // safariMatch ? console.log(''safariMatch'', safariMatch) : void 0; return firefoxMatch || chromeMatch || safariMatch; }

d - profundidad de la pila. 0 - devuelve este nombre de función, 1 - padre, etc .;
[0 + d] - solo para entender - que pasa;
firefoxMatch - funciona para safari, pero realmente tuve un poco de tiempo para probar, porque el propietario de mac había regresado después de fumar y me había alejado: ''(

Pruebas:

function limbo(){ for(let i = 0; i < 4; i++){ console.log(getName(i)); } } function lust(){ limbo(); } function gluttony(){ lust(); } gluttony();

Resultado:
Cromo:

Fitefox:

¡Esta solución fue creada solo por diversión ! No lo uses para proyectos reales. No depende de la especificación ES, solo depende de la realización del navegador. Después de la próxima actualización de chrome / firefox / safari, se puede romper.
Más que eso no hay procesamiento de errores (ha); si d será más que la longitud de la pila, obtendrá un error;
Para el patrón de mensajes de otros generadores de error, obtendrá un error;
Debe funcionar para las clases de ES6 ( .split(''.'').pop() ), pero aún así puede obtener un error;


Podría usar esto, pero no es para todos los navegadores, solo los que admiten Error.stack

function VamosRafa(){ var a = new Error().stack.match(/at (.*?) /); console.log(a[1]); } VamosRafa();

Por supuesto, esto es para la función actual, pero entiendes la idea.

¡Aclamaciones!


Puede usar la propiedad name para obtener el nombre de la función, a menos que esté usando una función anónima

Por ejemplo:

var Person = function Person () { this.someMethod = function () {}; }; Person.prototype.getSomeMethodName = function () { return this.someMethod.name; }; var p = new Person(); // will return "", because someMethod is assigned with anonymous function console.log(p.getSomeMethodName());

Ahora probemos con la función nombrada

var Person = function Person () { this.someMethod = function someMethod() {}; };

ahora puedes usar

// will return "someMethod" p.getSomeMethodName()


Puedes usar el nombre del constructor como:

{your_function}.prototype.constructor.name

este código simplemente devuelve el nombre de un método.


Sé que esta es una pregunta antigua, pero últimamente he estado enfrentando un problema similar al tratar de decorar algunos métodos de React Component, para propósitos de depuración. Como las personas ya han dicho, los arguments.caller y arguments.callee están prohibidos en modo estricto, que probablemente esté habilitado de forma predeterminada en su transpiling React. Puedes deshabilitarlo o he podido crear otro truco, porque en React todas las funciones de clase tienen nombre, puedes hacer esto:

Component.prototype.componentWillMount = function componentWillMount() { console.log(''Callee name: '', this.__proto__.constructor.toString().substr(0,30)); ... }


Tuve un problema similar y lo resolví de la siguiente manera:

Function.prototype.myname = function() { return this.toString() .substr( 0, this.toString().indexOf( "(" ) ) .replace( "function ", "" ); }

Este código implementa, de una manera más cómoda, una respuesta que ya leí aquí en la parte superior de esta discusión. Ahora tengo una función miembro que recupera el nombre de cualquier objeto de función. Aquí está el guión completo ...

<script language="javascript" TYPE="text/javascript"> Function.prototype.myname = function() { return this.toString() .substr( 0, this.toString().indexOf( "(" ) ) .replace("function ", "" ); } function call_this( _fn ) { document.write( _fn.myname() ); } function _yeaaahhh() { /* do something */ } call_this( _yeaaahhh ); </script>


Una forma sencilla de obtener el nombre de la función desde dentro de la función que está ejecutando.

function x(){alert(this.name)};x()


Usted no puede Las funciones no tienen nombres de acuerdo con el estándar (aunque mozilla tiene un atributo de este tipo), solo se pueden asignar a variables con nombres.

También tu comentario:

// access fully qualified name (ie "my.namespace.myFunc")

está dentro de la función my.namespace.myFunc.getFn

Lo que puedes hacer es devolver el constructor de un objeto creado por new

Para que puedas decir

var obj = new my.namespace.myFunc(); console.info(obj.constructor); //my.namespace.myFunc


lo que estás haciendo es asignar una función sin nombre a una variable. probablemente necesite una expresión de función nombrada en su lugar ( http://kangax.github.com/nfe/ ).

var x = function x() { console.log( arguments.callee.name ); } x();

Sin embargo, no estoy seguro de cuánto es el navegador cruzado; hay un problema con IE6 que hace que la fuga del nombre de su función al ámbito externo. también, los argumentos.callee están en desuso y resultarán en un error si estás usando el strict mode .



puede usar Error.stack para rastrear el nombre de la función y la posición exacta del lugar donde se encuentra.

Ver stacktrace.js


ES6 (inspirado por la respuesta de sendy halim a continuación):

myFunction.name

Explicación sobre MDN . A partir de 2015 funciona en nodejs y en todos los navegadores principales, excepto IE.

Nota: En las funciones enlazadas, aparecerá " bound <originalName> ". Tendrá que quitar el "límite" si desea obtener el nombre original.

ES5 (inspirado en la respuesta de Vlad):

Si tiene una referencia a la función, puede hacer:

function functionName( func ) { // Match: // - ^ the beginning of the string // - function the word ''function'' // - /s+ at least some white space // - ([/w/$]+) capture one or more valid JavaScript identifier characters // - /s* optionally followed by white space (in theory there won''t be any here, // so if performance is an issue this can be omitted[1] // - /( followed by an opening brace // var result = /^function/s+([/w/$]+)/s*/(/.exec( func.toString() ) return result ? result[ 1 ] : '''' // for an anonymous function there won''t be a match }

  • No he ejecutado pruebas unitarias sobre esto, ni he verificado diferencias de implementación, pero en principio debería funcionar, si no dejar un comentario.
  • Nota: no funcionará en funciones enlazadas
  • Nota: la caller que caller y el que callee caller se consideran en desuso.

[1] Lo incluyo aquí porque es legal y, con frecuencia, las herramientas de resaltado de sintaxis suficientes no tienen en cuenta el espacio en blanco entre el nombre de la función y el paréntesis. Por otro lado, no estoy al tanto de ninguna implementación de .toString () que incluya espacios en blanco aquí, por lo que puede omitirlo.

Como respuesta a la pregunta original, descartaría la herencia parásita e iría por algunos patrones de diseño OOP más tradicionales. Escribí un TidBits.OoJs para escribir cómodamente el código OOP en JavaScript con un conjunto de características que simula C ++ (aún no está completo, pero en su mayoría).

Por los comentarios, veo que le gustaría evitar pasar la información que los parent necesitan a su constructor. Sin embargo, debo admitir que los patrones de diseño tradicionales no lo salvarán de eso, ya que generalmente es una buena idea hacer que sus dependencias sean obvias y se cumplan.

También sugeriría alejarse de las funciones anónimas. Solo hacen la depuración y el perfilado de un PITA porque todo aparece como una "función anónima", y no tengo ningún beneficio que yo sepa.


Podrías usar Function.name :

En la mayoría de las implementaciones de JavaScript, una vez que tenga la referencia de su constructor en el alcance, puede obtener su nombre de cadena de su propiedad de nombre (por ejemplo, Function.name, o Object.constructor.name

Podrías usar Function.callee :

El método nativoargents.caller ha quedado en desuso, pero la mayoría de los navegadores admiten Function.caller , que devolverá el objeto invocador real (su cuerpo de código): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fcaller

Podrías crear un mapa fuente :

Si lo que necesita es la firma de la función literal (el "nombre" de la misma) y no el objeto en sí, es posible que tenga que recurrir a un poco más personalizado, como crear una referencia de matriz de los valores de cadena de API que necesitará acceso frecuente. Puede Object.keys() juntos usando Object.keys() y su matriz de cadenas, o buscar en la biblioteca de mapas fuente de Mozilla en GitHub, para proyectos más grandes: https://github.com/mozilla/source-map