[javascript] ¿Cómo obtener el nombre de la función desde esa función?


7 Answers

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

myFunction.name

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

Nota: En las funciones vinculadas esto dará " bound <originalName> ". Tendrás que quitar el "límite" si quieres obtener el nombre original.

ES5 (inspirado por 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 realizado pruebas unitarias sobre esto, ni diferencias de implementación verificadas, pero en principio debería funcionar, si no, dejar un comentario.
  • Nota: no funcionará en funciones enlazadas
  • Nota: la caller que caller y quien caller se consideran obsoletos.

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

Como respuesta a la pregunta original, dejaría de lado la herencia parasitaria y buscaría patrones de diseño OOP más tradicionales. Escribí TidBits.OoJs para escribir cómodamente el código OOP en JavaScript con un conjunto de características que imita C ++ (aún no completo, pero sobre todo).

Veo por los comentarios que le gustaría evitar pasar la información que los parent necesitan a su constructor. Debo admitir que los patrones de diseño tradicionales no te salvarán de eso, ya que generalmente se considera bueno hacer que tus dependencias sean obvias y forzadas.

También sugeriría alejarse de las funciones anónimas. Solo depuran y perfilan un PITA porque todo simplemente se muestra como "función anónima", y no tengo ningún beneficio que yo sepa.

Question

¿Cómo puedo acceder a un nombre de 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();



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

Ver stacktrace.js




Cualquier constructor expone un name propiedad, que es el nombre de la función. Accedes 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



Puede usar Function.name :

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

Puede usar Function.callee :

El método native arguments.caller ha quedado en desuso, pero la mayoría de los navegadores son compatibles con 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 literal de la función (el "nombre") y no el objeto en sí, puede que tenga que recurrir a algo un poco más personalizado, como crear una referencia de matriz de los valores de cadena API que necesitará para acceder con frecuencia 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




No puedes. Las funciones no tienen nombres de acuerdo con el estándar (aunque Mozilla tiene dicho atributo): 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 un nuevo

Entonces podrías decir

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



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');






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

function doSomething() {}

alert(doSomething.name); // alerts "doSomething"



Related