una tablas tabla obtener editar dinamicas descargar definicion datos con agregar javascript function

tablas - obtener datos de una tabla html javascript



Nombre de la función dinámica en javascript? (18)

Tengo esto:

this.f = function instance(){};

Me gustaría tener esto:

this.f = function ["instance:" + a](){};


actualizar

Como otros mencionaron, esta no es la solución más rápida ni la más recomendada. La solución de Marcosc a continuación es el camino a seguir.

Puedes usar eval:

var code = "this.f = function " + instance + "() {...}"; eval(code);


¡Gracias, Marcosc! Basándose en su respuesta, si quiere renombrar cualquier función, use esto:

// returns the function named with the passed name function namedFunction(name, fn) { return new Function(''fn'', "return function " + name + "(){ return fn.apply(this,arguments)}" )(fn) }


Creo que la mayoría de las sugerencias aquí son subóptimas, mediante el uso de soluciones eval, hacky o wrappers. A partir de ES2015, los nombres se deducen de la posición sintáctica de las variables y propiedades.

Entonces esto funcionará bien:

const name = ''myFn''; const fn = {[name]: function() {}}[name]; fn.name // ''myFn''

Resista la tentación de crear métodos de fábrica de funciones nombradas ya que no podría pasar la función desde el exterior y adaptarla a la posición sintáctica para inferir su nombre. Entonces ya es demasiado tarde. Si realmente lo necesita, debe crear un contenedor. Alguien hizo eso aquí, pero esa solución no funciona para las clases (que también son funciones).

Se ha escrito una respuesta mucho más detallada con todas las variantes descritas aquí: https://.com/a/9479081/633921


En motores recientes, puedes hacer

function nameFunction(name, body) { return {[name](...args) {return body(...args)}}[name] } const x = nameFunction("wonderful function", (p) => p*2) console.log(x(9)) // => 18 console.log(x.name) // => "wonderful function"


Esta es la MEJOR solución, mejor que la new Function(''return function name(){}'')() .

Eval es la solución más rápida:

var name = ''FuncName'' var func = eval("(function " + name + "(){})")


Esta función de utilidad combina múltiples funciones en una sola (usando un nombre personalizado), el único requisito es que las funciones proporcionadas estén correctamente "alineadas" al inicio y al final de su primicia.

const createFn = function(name, functions, strict=false) { var cr = `/n`, a = [ ''return function '' + name + ''(p) {'' ]; for(var i=0, j=functions.length; i<j; i++) { var str = functions[i].toString(); var s = str.indexOf(cr) + 1; a.push(str.substr(s, str.lastIndexOf(cr) - s)); } if(strict == true) { a.unshift(''/"use strict/";'' + cr) } return new Function(a.join(cr) + cr + ''}'')(); } // test var a = function(p) { console.log("this is from a"); } var b = function(p) { console.log("this is from b"); } var c = function(p) { console.log("p == " + p); } var abc = createFn(''aGreatName'', [a,b,c]) console.log(abc) // output: function aGreatName() abc(123) // output this is from a this is from b p == 123


Estabas cerca:

this["instance_" + a] = function () {...};

{...};


Esto básicamente lo hará en el nivel más simple:

"use strict"; var name = "foo"; var func = new Function( "return function " + name + "(){ alert(''sweet!'')}" )(); //call it, to test it func();

Si quieres ser más elegante, tengo un artículo escrito sobre " Nombres de funciones dinámicas en JavaScript ".


Hay dos métodos para lograr esto, y tienen sus pros y sus contras.

name propiedad definición

Definición de la propiedad del name inmutable de una función.

Pros

  • Cada personaje está disponible para el nombre. (ej.. () 全 {}/1/얏호/ :D #GO(@*#%! /* )

Contras

  • El nombre sintáctico ("expresivo") de la función puede no corresponderse con el valor de propiedad de su name .

Evaluación de expresión de función

Hacer una expresión de función nombrada y evaluarla con el constructor de Function .

Pros

  • El nombre sintáctico ("expresivo") de la función siempre se corresponde con el valor de propiedad de su name .

Contras

  • Los espacios en blanco (y etc.) no están disponibles para el nombre.
  • Expresión inyectable (por ejemplo, para input (){}/1// , la expresión es return function (){}/1//() {} , da NaN lugar de una función.).

const demoeval = expr => (new Function(`return ${expr}`))(); // `name` property definition const method1 = func_name => { const anon_func = function() {}; Object.defineProperty(anon_func, "name", {value: func_name, writable: false}); return anon_func; }; const test11 = method1("DEF_PROP"); // No whitespace console.log("DEF_PROP?", test11.name); // "DEF_PROP" console.log("DEF_PROP?", demoeval(test11.toString()).name); // "" const test12 = method1("DEF PROP"); // Whitespace console.log("DEF PROP?", test12.name); // "DEF PROP" console.log("DEF PROP?", demoeval(test12.toString()).name); // "" // Function expression evaluation const method2 = func_name => demoeval(`function ${func_name}() {}`); const test21 = method2("EVAL_EXPR"); // No whitespace console.log("EVAL_EXPR?", test21.name); // "EVAL_EXPR" console.log("EVAL_EXPR?", demoeval(test21.toString()).name); // "EVAL_EXPR" const test22 = method2("EVAL EXPR"); // Uncaught SyntaxError: Unexpected identifier


La function[i](){} sintaxis function[i](){} implica un objeto con valores de propiedad que son funciones, function[] , indexado por el nombre, [i] .
Así
{"f:1":function(){}, "f:2":function(){}, "f:A":function(){}, ... } ["f:"+i] .

{"f:1":function f1(){}, "f:2":function f2(){}, "f:A":function fA(){}} ["f:"+i] preservará identificación del nombre de la función. Ver notas a continuación con respecto a :

Asi que,

javascript: alert( new function(a){ this.f={"instance:1":function(){}, "instance:A":function(){}} ["instance:"+a] }("A") . toSource() );

muestra ({f:(function () {})}) en FireFox.
(Esta es casi la misma idea que esta solución , solo que utiliza un objeto genérico y ya no rellena directamente el objeto de la ventana con las funciones).

Este método rellena explícitamente el entorno con la instance:x .

javascript: alert( new function(a){ this.f=eval("instance:"+a+"="+function(){}) }("A") . toSource() ); alert(eval("instance:A"));

muestra

({f:(function () {})})

y

function () { }

Aunque la función de propiedad f referencia a una anonymous function y no instance:x , este método evita varios problemas con esta solución .

javascript: alert( new function(a){ eval("this.f=function instance"+a+"(){}") }("A") . toSource() ); alert(instanceA); /* is undefined outside the object context */

muestra solo

({f:(function instanceA() {})})

  • El incrustado : hace que la function instance:a(){} javascript function instance:a(){} inválida.
  • En lugar de una referencia, la definición de texto real de la función es analizada e interpretada por eval .

Lo siguiente no es necesariamente problemático,

  • La función instanceA no está disponible directamente para su uso como instanceA()

y entonces es mucho más consistente con el contexto del problema original.

Teniendo en cuenta estas consideraciones,

this.f = {"instance:1": function instance1(){}, "instance:2": function instance2(){}, "instance:A": function instanceA(){}, "instance:Z": function instanceZ(){} } [ "instance:" + a ]

mantiene el entorno informático global con la semántica y la sintaxis del ejemplo OP todo lo posible.


La respuesta más votada ya tiene definido el cuerpo de la función [String]. Estaba buscando la solución para renombrar el nombre de la función ya declarada y, finalmente, después de una hora de lucha, lo he solucionado. Eso:

  • toma la función declarada alredy
  • lo analiza en [String] con el método .toString()
  • luego sobrescribe el nombre (de la función nombrada) o agrega el nuevo (cuando es anónimo) entre la function y (
  • luego crea la nueva función renombrada con el new Function() constructor new Function()

function nameAppender(name,fun){ const reg = /^(function)(?:/s*|/s+([A-Za-z0-9_$]+)/s*)(/()/; return (new Function(`return ${fun.toString().replace(reg,`$1 ${name}$3`)}`))(); } //WORK FOR ALREADY NAMED FUNCTIONS: function hello(name){ console.log(''hello '' + name); } //rename the ''hello'' function var greeting = nameAppender(''Greeting'', hello); console.log(greeting); //function Greeting(name){...} //WORK FOR ANONYMOUS FUNCTIONS: //give the name for the anonymous function var count = nameAppender(''Count'',function(x,y){ this.x = x; this.y = y; this.area = x*y; }); console.log(count); //function Count(x,y){...}


Los métodos dinámicos de un objeto se pueden crear utilizando Object Literal Extensions provistos por ECMAScript 2015 (ES6):

const postfixes = [''foo'', ''bar'']; const mainObj = {}; const makeDynamic = (postfix) => { const newMethodName = ''instance: '' + postfix; const tempObj = { [newMethodName]() { console.log(`called method ${newMethodName}`); } } Object.assign(mainObj, tempObj); return mainObj[newMethodName](); } const processPostfixes = (postfixes) => { for (const postfix of postfixes) { makeDynamic(postfix); } }; processPostfixes(postfixes); console.log(mainObj);

El resultado de ejecutar el código anterior es:

"called method instance: foo" "called method instance: bar" Object { "instance: bar": [Function anonymous], "instance: foo": [Function anonymous] }


Me puede estar perdiendo lo obvio aquí, pero ¿qué hay de malo con solo agregar el nombre? las funciones se invocan independientemente de su nombre. los nombres solo se usan por razones de alcance. si lo asigna a una variable, y está dentro del alcance, se puede invocar. sucede cuando estás ejecutando una variable que resulta ser una función. si debe tener un nombre para los motivos de identificación cuando se depura, insértelo entre la función de palabra clave y la llave de apertura.

var namedFunction = function namedFunction (a,b) {return a+b}; alert(namedFunction(1,2)); alert(namedFunction.name); alert(namedFunction.toString());

un enfoque alternativo es envolver la función en una corrección externa renombrada, que también puede pasar a una envoltura externa, si no desea ensuciar el espacio de nombres circundante. si quiere crear dinámicamente la función a partir de cadenas (lo que ocurre en la mayoría de estos ejemplos), es trivial cambiar el nombre del origen para hacer lo que quiera. sin embargo, si desea cambiar el nombre de las funciones existentes sin afectar su funcionalidad cuando se le llama a otra parte, un ajuste es la única forma de lograrlo.

(function(renamedFunction) { alert(renamedFunction(1,2)); alert(renamedFunction.name); alert(renamedFunction.toString()); alert(renamedFunction.apply(this,[1,2])); })(function renamedFunction(){return namedFunction.apply(this,arguments);}); function namedFunction(a,b){return a+b};


Para configurar el nombre de una función anónima existente :
(Basado en la respuesta de @Marcosc)

var anonymous = function() { return true; } var name = ''someName''; var strFn = anonymous.toString().replace(''function '', ''return function '' + name); var fn = new Function(strFn)(); console.log(fn()); // —> true

Demo



Qué pasa

this.f = window["instance:" + a] = function(){};

El único inconveniente es que la función en su método toSource no indicaría un nombre. Eso suele ser solo un problema para los depuradores.


Tuve mejor suerte al combinar la respuesta de Darren y la respuesta de kyernetikos .

const nameFunction = function (fn, name) { return Object.defineProperty(fn, ''name'', {value: name, configurable: true}); }; /* __________________________________________________________________________ */ let myFunc = function oldName () {}; console.log(myFunc.name); // oldName myFunc = nameFunction(myFunc, ''newName''); console.log(myFunc.name); // newName

Nota: configurable se establece en true para que coincida con la especificación ES2015 estándar para Function.name 1

Esto ayudó especialmente a evitar un error en el paquete web similar a este .

Actualización: estaba pensando en publicar esto como un paquete npm, pero este paquete de sindresorhus hace exactamente lo mismo.

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name

function myFunction() { console.log(''It works!''); } var name = ''myFunction''; window[name].call();