【问题标题】:javascript: create named function but its name is stored in a variablejavascript:创建命名函数,但其​​名称存储在变量中
【发布时间】:2013-08-12 13:48:37
【问题描述】:

我有一种情况,我需要在我的应用程序中的某个时刻输入构造函数的名称

instance.constructor.name

但是,当我创建构造函数时,我将其名称存储在一个变量中。所以,让你知道我想要什么

var nameOfTheFunction = "Test" ;
var BarFoo = function() { /* do stuff */ } ;
BarFoo.name = nameOfTheFunction ;

这当然行不通,因为 name 属性是只读的。

那么是否可以动态创建一个构造函数,其最终结果是它创建的实例将具有的结果

instance.constructor.name === nameOfTheFunction

更新:在下面查看我的评论,因为它符合我的要求。不过,对于这个问题,感谢答案,我最初是在寻找这个

(new Function( 'base', 'return function ' + Foo.name + '(){ base.apply(this, arguments); };'))(Foo) ;

这个解决方案的问题在于,这里创建的东西不是 Foo 的实例,除非您执行 this 之类的操作,这让我在下面的评论中找到了解决方案!

【问题讨论】:

  • 我真的不知道这样做的好处。你能解释一下你正在尝试什么吗?
  • 你说得对,我找到了更简单的方法:jsfiddle.net/jeanluca/8ztAU/1

标签: javascript function constructor instance


【解决方案1】:

我不认为eval 是个坏主意。但我建议使用工厂函数,这样你就不必用字符串文字编写函数的所有代码:

function createNamedFunction(name, func) {
    eval("var f = function " + name + "(){return func.apply(this, arguments);};");
    return f;
}

var t = createNamedFunction("myFunc", function () {
    console.log("hello");
});

console.log(t.name);  //myFunc
t();  //hello

FIDDLE

编辑

您也可以直接操作函数的字符串表示,因此您不必使用apply 方法:

function createNamedFunction(name, func) {
    var fstr = func.toString(),
        index = fstr.indexOf("(");
    fstr = "function " + name + fstr.substring(index);
    eval("var f = " + fstr + ";");
    return f;
}

【讨论】:

  • 你认为应该使用 'eval' 而不是 'new Function(){..}' 吗?
  • 原因在这里@Jeanluca Scaljeri:注意:使用 Function 构造函数创建的函数不会为其创建上下文创建闭包;它们总是在窗口上下文中运行(除非函数体以“use strict”; 语句开头,在这种情况下上下文未定义)。来自developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • @JeanlucaScaljeri 我不确定new Function(){...} 会如何帮助您。据我所知,它不允许您指定名称?
【解决方案2】:

如果您在浏览器端,您可以使用以下解决方案:

Javascript: Dynamic function names

当然,这会使你的函数成为一个全局变量。

编辑:如果您绝对想使用eval,您可以使用以下构造:

function generateFunction(functionName) {
    function __REPLACE__() {
        // your function's code
    }
    eval(__REPLACE__.toString().replace('__REPLACE__', functionName));
    return functionName;
}

【讨论】:

  • 感谢链接!我认为“新功能”比“评估”更好。你为什么认为它会产生全局变量? var Consr = new Function(){ '返回函数' + name + '(){}'; }
  • 如果您将函数声明为 Window 的属性,则每个有权访问 window 的对象(即一切)都将您的函数作为其范围内的变量。你说得对,new Function()eval() 好。
  • 使用我编写的第二个解决方案,您可以将函数编写为普通的 JavaScript 函数,然后将其作为参数传递给 generateFunction()
  • 注意:使用 Function 构造函数创建的函数不会为其创建上下文创建闭包;它们总是在窗口上下文中运行(除非函数体以“use strict”; 语句开头,在这种情况下上下文未定义)。来自developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
【解决方案3】:

在你的情况下,我认为我们可以使用eval

var nameOfTheFunction = "Test" ;
var BarFoo = eval("function " + nameOfTheFunction + "() { /* do stuff */ }") ;

【讨论】:

  • Eval 不是一个好的解决方案!不要使用评估!不安全。
  • @AwakeZoldiek “这不安全”在这里不是相关的原因。要么解释你的意思,要么给出更好的理由
  • Eval 是一个安全问题,因为您正在执行不受信任的源代码。如果攻击者可以修改字符串连接中使用的参数,他们就可以在用户浏览器中执行恶意代码并运行漏洞利用、窃取 cookie 等等。
  • @AwakeZoldiek eval 并不比浏览器的控制台/开发工具更危险。谁说过“不受信任”的源代码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 2018-05-29
  • 2019-01-12
  • 2018-02-12
相关资源
最近更新 更多