javascript中的动态函数名?

javascript中的动态函数名?,javascript,function,Javascript,Function,我有这个: this.f = function instance(){}; this.f = function ["instance:" + a](){}; 我想要这个: this.f = function instance(){}; this.f = function ["instance:" + a](){}; 更新 正如其他人所提到的,这不是最快也不是最推荐的解决方案。这是一条路要走 您可以使用eval: 那怎么办 this.f = window["instance:" + a]

我有这个:

this.f = function instance(){};
this.f = function ["instance:" + a](){};
我想要这个:

this.f = function instance(){};
this.f = function ["instance:" + a](){};
更新 正如其他人所提到的,这不是最快也不是最推荐的解决方案。这是一条路要走

您可以使用eval:

那怎么办

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

唯一的缺点是toSource方法中的函数不会指示名称。这通常只是调试器的问题

语法
function[i](){}
表示一个对象,该对象的属性值为函数
function[]
,由名称
[i]
索引
因此
{“f:1”:function(){},“f:2”:function(){},“f:A”:function(){},…}[“f:+i]

{“f:1”:函数f1(){},“f:2”:函数f2(){},“f:A”:函数fA(){}[“f:+i]
将保留函数名标识。请参阅下面有关
的注释

所以

在FireFox中显示
({f:(函数(){})})

(这与基本相同,只是它使用一个通用对象,不再直接用函数填充窗口对象。)

此方法使用
实例:x
显式填充环境

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

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

虽然属性函数
f
引用了一个
匿名函数
,而不是
实例:x
,但此方法避免了使用时出现的几个问题

仅显示

({f:(function instanceA() {})})
  • 嵌入的
    使javascript
    函数实例:a(){}
    无效
  • 函数的实际文本定义由
    eval
    解析和解释,而不是引用
以下内容不一定有问题

  • instanceA
    函数不能直接用作
    instanceA()
这与最初的问题背景更为一致

基于这些考虑,

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

尽可能使用OP示例的语义和语法维护全局计算环境。

这基本上可以在最简单的级别上完成:

"use strict";
var name = "foo";
var func = new Function(
     "return function " + name + "(){ alert('sweet!')}"
)();

//call it, to test it
func();

如果你想变得更花哨,我写了一篇关于“”的文章

谢谢你,马可!根据他的答案,如果您想重命名任何函数,请使用以下命令:

// 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)
}

用于设置现有匿名函数的名称:
(基于@Marcosc的回答)


注意:不要这样做/

这是最好的解决方案,比新函数('return Function name(){}')()更好

Eval是最快的解决方案:


您可以使用Object.defineProperty,如中所述:


在最近的引擎中,您可以

函数名函数(名称、正文){
返回{[name](…args){returnbody(…args)}}[name]
}
常数x=nameFunction(“奇妙的函数”,(p)=>p*2)
console.log(x(9))/=>18

console.log(x.name)//=>“奇妙的功能”
可以使用ECMAScript 2015(ES6)提供的对象文字扩展创建对象的动态方法:

运行上述代码的输出为:

"called method instance: foo"
"called method instance: bar"
Object {
  "instance: bar": [Function anonymous],
  "instance: foo": [Function anonymous]
}
你在附近:


this[“实例”+a]=函数(){…}此实用程序函数将多个函数合并为一个函数(使用自定义名称),唯一的要求是所提供的函数在其开始和结束时正确地“新划线”

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
const createFn=function(名称、函数、strict=false){
var cr=`\n`,a=['返回函数'+name+'(p){'];

对于(var i=0,j=functions.length;i有两种方法可以实现这一点,它们各有优缺点


名称
属性定义 定义函数的不可变的
名称
属性

赞成的意见
  • 名称中的每个字符都可用。(例如,
    ()全 {}/1/얏호/ :D#GO(@*#%!/*
欺骗
  • 函数的语法(“表达式”)名称可能与其
    名称
    属性值不一致

函数表达式求值 制作命名函数表达式并使用
函数
构造函数对其进行求值

赞成的意见
  • 函数的语法(“表达式”)名称始终与其
    名称
    属性值相对应
欺骗
  • 名称不能使用空格(等)
  • 表达式可注入(例如,对于输入
    (){}/1//
    ,表达式是
    返回函数(){}/1//(){}
    ,给出
    NaN
    ,而不是函数)


投票最多的答案已经定义了[String]函数体。我一直在寻找重命名已声明函数名称的解决方案,经过一个小时的努力,终于解决了这个问题。它:

  • 接受alredy声明的函数
  • 使用
    .toString()
    方法将其解析为[String]
  • 然后在
    函数
  • 然后使用
    newfunction()
    构造函数创建新的重命名函数
函数名appender(名称,乐趣){
常量reg=/^(函数)(?:\s*|\s+([A-Za-z0-9_$]+)\s*)(\()/;
return(新函数(`return${fun.toString().replace(reg,`1${name}$3`)}'))();
}
//用于已命名的函数:
函数hello(name){
log('hello'+name);
}
//重命名“hello”函数
var greeting=nameapper('greeting',hello);
console.log(问候语);//函数问候语(名称){…}
//为匿名函数工作:
//给出匿名函数的名称
var count=nameAppender('count',函数(x,y){
这个.x=x;
这个。y=y;
该面积=x*y;
}); 

console.log(count);//函数count(x,y){…}
我可能缺少这里显而易见的内容,但是仅仅添加名称有什么错呢?函数会被调用,而不管它们的名称如何。名称只是用于作用域的原因。如果将其分配给变量,并且它在作用域中,则可以调用它。在
function myFunction() {
    console.log('It works!');
}

var name = 'myFunction';

window[name].call();
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
var name = 'FuncName'
var func = eval("(function " + name + "(){})")
var myName = "myName";
var f = function () { return true; };
Object.defineProperty(f, 'name', {value: myName, writable: false});
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);
"called method instance: foo"
"called method instance: bar"
Object {
  "instance: bar": [Function anonymous],
  "instance: foo": [Function anonymous]
}
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
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
const name = 'myFn';
const fn = {[name]: function() {}}[name];
fn.name // 'myFn'
const target = {};

const handler = {
  get: function (target, name) {
    return (myArg) => {
      return new Promise(resolve => setTimeout(() => resolve('some' + myArg), 600))
    }
  }
};

const proxy = new Proxy(target, handler);

(async function() {
  const result = await proxy.foo('string')
  console.log('result', result) // 'result somestring' after 600 ms
})()
let functionName = "testFunction";
let param = {"param1":1 , "param2":2};

var func = new Function(
   "return " + functionName 
)();

func(param);

function testFunction(params){
   alert(params.param1);
}
let functionName = "testFunction(params)";
let param = {"param1":"1" , "param2":"2"};
let functionBody = "{ alert(params.param1)}";

var func = new Function(
    "return function " + functionName + functionBody 
)();

func(param);
const USER = 'user';

const userModule = {
  [USER + 'Action'] : function () { ... }, 
  [USER + 'OnClickHandler'] : function () { ... }, 
  [USER + 'OnCreateHook'] : function () { ... }, 
}