Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将JavaScript函数对象作为字符串从其名称中获取?_Javascript - Fatal编程技术网

将JavaScript函数对象作为字符串从其名称中获取?

将JavaScript函数对象作为字符串从其名称中获取?,javascript,Javascript,在JavaScript中,如果变量中有一个字符串,是否有方法获取对具有匹配名称的函数对象的引用?请注意,jQuery对我是可用的,因此我也可以使用它的任何助手方法 例如: myFunction = function(){}; var func_name = "myFunction"; var myFunctionPtr = ??? //how to get the function from the name 如果您知道这是一个可以使用的全局函数,请感谢: var functPtr = w

在JavaScript中,如果变量中有一个字符串,是否有方法获取对具有匹配名称的函数对象的引用?请注意,jQuery对我是可用的,因此我也可以使用它的任何助手方法

例如:

myFunction = function(){};

var func_name = "myFunction";
var myFunctionPtr = ???  //how to get the function from the name

如果您知道这是一个可以使用的全局函数,请感谢:

var functPtr = window[func_name];
//functPtr()

否则,将窗口替换为包含函数的父对象。

此[func_name]应为您提供函数

var myfunc = this[func_name];
myfunc();
使用eval:

myFunction = function(){};

var func_name = "myFunction";
var myFunctionPtr = eval(func_name);

我刚刚在Firebug中做了一个快速测试,通过简单地
eval()
ing名称,我就可以从名称中获取函数。。。使用
eval()
我感觉很脏,但它似乎很好地完成了这里的工作

var myFunctionPtr = eval(func_name);

一种安全的方法是在测试其类型时对声称的函数进行沙箱处理:

function isFunction(expr) {
    function sandboxTemplate() {
        var window, document, alert; // etc.

        try {
            return typeof $expr$ == "function";
        } catch (e) {
            return false;
        }
    }

    try {
        var sandbox = new Function(
            sandboxTemplate.toString().replace("$expr$", expr)
            + "return sandboxTemplate()");
        return sandbox();
    } catch (e) {
        return false;
    }
}

function test(expr) {
    document.write("<div>\"" + expr + "\" <b>is "
        + (isFunction(expr) ? "" : "not ")
        + "</b>a function</div>");
}

/* Let's do some testing */

function realFunction() {
}

test("realFunction");       // exists!
test("notHere");            // non-existent
test("alert('Malicious')"); // attempt to execute malicious code!
test("syntax error {");     // attempt to blow us up!
函数是函数(expr){
函数sandboxTemplate(){
变量窗口、文档、警报;//等。
试一试{
返回类型$expr$==“函数”;
}捕获(e){
返回false;
}
}
试一试{
var sandbox=新函数(
sandboxTemplate.toString().replace(“$expr$”,expr)
+“返回sandboxTemplate()”;
返回沙盒();
}捕获(e){
返回false;
}
}
功能测试(expr){
document.write(“\”+expr+“\”是“
+(isFunction(expr)?“”:“not”)
+“职能”);
}
/*让我们做一些测试*/
函数realFunction(){
}
测试(“realFunction”);//存在!
测试(“无”);//不存在
测试(“警报(‘恶意’)”);//试图执行恶意代码!
test(“语法错误{”);//试图炸毁我们!
输出:

  • “realFunction”是一个函数
  • “notHere”不是一个函数
  • “警报(‘恶意’)”不是功能
  • “语法错误{”不是函数
沙箱代码可以用更简洁的方式编写,但我喜欢使用“模板”函数,而不是将JS代码作为字符串文本嵌入


哦,这在不使用
eval
的情况下很好地实现了这一点——尽管有人可能会说,使用函数构造函数与
eval
没有什么不同,但这从来都不是首选的方法。与其将函数名保留在
func\u name
中,不如在某些情况下成功地保留对函数的引用ng类似于
函数调用

如果您绝对需要将函数引用保持为字符串,则通常会使用哈希表将任意名称映射到变量(JS具有一流的函数,这使其成为可能)

(我不知道为什么,这是一个如此微小的脚本:)

有人建议您使用
eval(func_name)
——但是由于JS的作用域,这可能很快就会失控


您还将您的
myFunction=function(){};
声明为全局变量。一方面,它允许您将其作为
window[func\u name]
引用,但另一方面它污染了全局范围。

找到了该函数,然后调用它们

autoCallBack : function(_action){
            $(".module").each(function(){
                var modulName = $(this).attr("id");
                if( isFunction(modulName) ){
                    eval(modulName)();
                }
            });
        }

isFunction : function(_functionName){
        try {
            eval(_functionName);
        } catch (error) {
            return false;
        }
    return true;
}
这取决于函数的声明位置和方式

如果它是全局的,而不是通过
let name=…
const name=…
语法声明的(并且它不是使用
class
声明的类构造函数),则可以通过在全局对象上查找它作为属性来进行检查。(这些警告都是ES2015的内容;下面将详细介绍。)您可以在全局范围内的松散模式下通过
this
获取对全局对象的引用;浏览器还为您提供了一个称为
窗口的全局对象。因此,假设浏览器:

if (typeof window[func_name] === "function") {
    // ....
}
如果它可能不是全局的,而只是在范围内,因为您的代码关闭了它,或者如果它是使用我提到的ES2015机制之一创建的,那么除了
eval
,实在没有什么好的检查方法:

if (eval("typeof " + func_name) === "function") {
    // ....
}
使用
eval
是最后的手段,你必须只在严格控制输入的情况下使用它。但是当你不得不这样做,并且你有严格控制的输入时,这是可以的


关于ES2015的注意事项:

新的
let
const
class
是非常有趣的beasties:在全局范围内使用时,它们创建全局对象,但不在全局对象上创建属性。截至ES2015,尽管全局对象的所有属性都是全局对象,但并非所有全局对象都是全局对象的属性。它都是全局对象的一部分试图控制严重污染的全局名称空间,并为JavaScript绑定模型带来更大的安全性(现在我们有了真正的模块)

因此(请注意,这将仅在最先进的浏览器中运行):

//全局范围,在浏览器中(因为我使用了'window'和'document.body'),它
//实现ES2015的这一方面(在我写这篇文章时,Firefox的SpiderMonkey
//没有,Chrome的V8在最新的Chrome上有;除了SpiderMonkey和IE
//快速赶上(没有测试IE Edge,可能它已经存在)
//此行为不需要严格模式,但目前仅限于V8
//在严格模式下支持块范围的构造。
“严格使用”;
设tbody=setup();
//老式var:在全局对象上创建属性,因此
//我们得到“函数,函数”
var f1=function(){/*…*/};
结果(“var声明”、类型f1、类型窗口[“f1”]);
//函数声明:在全局对象上创建属性,因此
//“功能,功能”
函数f2(){}
结果(“函数声明”、类型f2、类型窗口[“f2”]);
//`let`声明:不在全局对象上创建属性,因此
//函数,未定义
设f3=function(){/*…*/};
结果(“let声明”、类型f3、类型窗口[“f3”]);
//`const`声明:不在全局对象上创建属性,因此
//函数,未定义
常量f4=函数(){/*…*/};
结果(“常量声明”,类型为f4,类型为窗口[“f4”]);
//“阶级
if (eval("typeof " + func_name) === "function") {
    // ....
}
//    functions.js
var funcOne = function(){
                   console.log('function ONE called')
              }
module.exports={
    //  name_exported : internal_name
    funcOne : funcOne
}
//    index.js
var methods = require('./functions.js')   // path to functions.js
methods['funcOne']()
> node index.js
> function ONE called