这可能看起来有点奇怪,但在创建动态事件监听器时可以派上用场,我会尽力解释我想要实现的目标。
我有一个变量,我想创建一个以该变量值命名的函数。以下是例子:
var functionName = "foo";
// Now I want to create a function named foo. foo is a tring
function [functionName](){
alert('nothing really');
}
foo(); //Should alert "nothing really"
谢谢!
答案 0 :(得分:6)
2016年更新的答案:
“但是,这正在改变......”下面原始答案的一部分已经改变。 ES2015(“ES6”)一年前发布,现在终于 最终符合其中一个鲜为人知的方面:Function#name
。
从ES2015开始,尽管使用“匿名”函数表达式创建了此函数,但该函数仍有一个名称:
var f = function() { };
其名称为f
。这取决于the specification(或new one for ES2016)在几十个不同的地方(搜索使用SetFunctionName
的位置)。在这种特殊情况下,它是因为它获取了它所分配的变量的名称。 (我在那里使用了var
而不是新的let
,以避免给人的印象是这是let
的一个特征。它不是。但是因为这是ES2015 ,我将从现在开始使用let
...)
现在,你可能会想“这对我没有帮助,因为f
是硬编码的”,但坚持我。
此功能的名称为f
:
let obj = {
f: function() { }
};
它获取了分配给(f
)的属性的名称。这就是ES2015的另一个便利功能生效的地方:对象初始化器中的计算属性名称。我们可以使用计算属性名称来代替名称f
。
let functionName = "f";
let obj = {
[functionName]: function() { }
};
计算属性名称语法评估[]
中的表达式,然后将结果用作属性名称。并且由于该函数从它所分配的属性中获取了一个真实的名称,我们可以使用运行时确定的名称创建一个函数。
如果我们不想要任何对象,我们不需要保留它:
let functionName = "f";
let f = ({
[functionName]: function() { }
})[functionName];
用对象创建对象,然后从对象中抓取函数并抛弃对象。
当然,如果你想使用词汇this
,它可能是一个箭头函数:
let functionName = "f";
let f = ({
[functionName]: () => { }
})[functionName];
以下是一个示例,适用于Chrome 51及更高版本,但尚不适用于其他许多内容:
// Get the name
let functionName = prompt(
"What name for the function?",
"func" + Math.floor(Math.random() * 10000)
);
// Create the function
let f = ({
[functionName]: function() { }
})[functionName];
// Check the name
if (f.name !== functionName) {
console.log("This browser's JavaScript engine doesn't fully support ES2015 yet.");
} else {
console.log("The function's name is: " + f.name);
}
2014年的原始答案:
除非您希望该功能是全局的,否则在不使用eval
的情况下,字面要求的内容是不可能的。如果你这样做,你可以这样做:
// Creates global function
window[functionName] = function() { };
请注意,该函数实际上不会有名称(在调用堆栈中等等;但这种情况正在发生变化,请参见下面的注释),但您可以使用变量中的名称来调用它。例如:
var functionName = "foo";
window[functionName] = function() {
console.log("I got called");
};
foo(); // Outputs "I got called"
这只是使用对象属性的更通用概念的特定情况。这是附加到对象属性的非全局函数:
var functionName = "foo";
var obj = {}; // The object
obj[functionName] = function() { }; // The function
obj[functionName] = function() {
console.log("I got called");
};
obj.foo(); // Outputs "I got called"
在这两种情况下,它都有效,因为在JavaScript中,您可以使用点分表示法和文字属性名称(obj.foo
)引用属性,或使用括号表示法和< em> string 属性名称(obj["foo"]
)。当然,在后一种情况下,您可以使用任何求值为字符串的表达式。
为了完整起见,您可以使用eval
:
(function() { // This scoping function is just to emphasize we're not at global scope
var functionName = "foo";
eval("function " + functionName + "() { print('I got called'); }");
foo();
})();
以下是关于功能名称的“下面注释”:截至当前标准ECMAScript第5版,此功能没有名称:
var f = function() { };
这是一个匿名函数定义。这是另一个:
obj.f = function() { };
在第一个中,变量具有名称(f
),但该函数没有;在第二个,对象上的属性有一个名称,但该函数没有。
然而,这种情况正在发生变化。从第6版规范(目前仍为草案)开始,引擎将为函数命名f
,即使上面的表达式也是如此。它还会从稍微复杂的表达式中推断出名称。 Firefox的引擎至少已经完成了一段时间,Chrome已经开始了,它将在下一版规范中指定。
答案 1 :(得分:2)
&#34;全球&#34; JavaScript中的函数只是全局上下文对象的属性(浏览器中为window
)。所以你可以用这种方式做你想要的事情:
var functionName = 'foo';
window[functionName] = function() {
alert('nothing really');
}