是否可以在函数作用域而不是全局作用域下运行通过Function构造函数创建的函数

时间:2013-12-19 06:32:16

标签: javascript function

我有一个字符串格式的函数名称,并希望将其转换为函数引用。

我可以使用eval或Function构造函数或window [name]将字符串转换为正确的函数引用。

但是,我不希望将函数名称公开为全局,即窗口对象。我打算创建包含在匿名函数下的函数。但是,如果我使用Function构造函数,它不会在匿名函数范围内运行。

(function(){
    var k = function(){alert(1);};
    var kRef = new Function("return k");
    kRef();
})()

但是,如果我使用eval而不是Function构造函数,它将在匿名函数的范围内运行。

(function(){
    var k = function(){alert(1);};
    var kRef = eval("k");
    kRef();
})()

由于我们在匿名函数中使用Function构造函数创建函数,为什么它不在函数作用域中运行?为什么eval在匿名函数范围内运行。

2 个答案:

答案 0 :(得分:3)

这实际上是有意的。引用the doc

  

注意:使用Function构造函数创建的函数不会创建   封闭他们的创作背景;他们总是在   全球范围。运行它们时,它们只能访问   他们自己的局部变量和全局变量,而不是范围内的变量   其中调用了Function构造函数。这不同于   使用eval和函数表达式的代码。

反过来,这个描述只是改写standard中给出的那个:

  

15.3.2.1 新功能(p1,p2,...,pn,body)

     

[...]   11.返回按照13.2传递中的指定创建的新Function对象   P作为FormalParameterListopt和body作为FunctionBody。的通   在全局环境中作为Scope参数并严格按照   严格的旗帜。

但是,我不确定为什么不使用函数哈希而不是试图评估它们的存在。例如:

var method = {
  first: function() { alert('I am first'); },
  second: function() { console.log('I am second'); }
};

...然后根据一些标准选择要使用的功能:

method[thatShouldBeUsed]();

答案 1 :(得分:1)

您可以使用对象来存储函数:

var funcs = {func1 : function(x1, x2){ ... },
             func2 : function(x1, x2){ ... },
             ...
             funcN : function(x1, x2){ ... }};

然后您可以按名称访问它们

var result = funcs[name](x1, x2);

所有这些都不会污染全局对象。