我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
当前回答
不使用eval('function()'),您可以使用new function(strName)创建一个新函数。下面的代码是使用FF, Chrome, IE测试的。
<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">
function test() {
try {
var fnName = "myFunction()";
var fn = new Function(fnName);
fn();
} catch (err) {
console.log("error:"+err.message);
}
}
function myFunction() {
console.log('Executing myFunction()');
}
</script>
其他回答
这里有几个executeByName函数,它们工作得很好,除非name包含方括号——这是我遇到的问题——因为我有动态生成的名称。因此,上述函数将失败的名称
小部件应用。[toggleFolders’‘872LfCHc] []
作为补救措施,我也考虑了这一点,也许有人会发现它很有用:
由CoffeeScript生成:
var executeByName = function(name, context) {
var args, func, i, j, k, len, len1, n, normalizedName, ns;
if (context == null) {
context = window;
}
args = Array.prototype.slice.call(arguments, 2);
normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.');
ns = normalizedName.split(".");
func = context;
for (i = j = 0, len = ns.length; j < len; i = ++j) {
n = ns[i];
func = func[n];
}
ns.pop();
for (i = k = 0, len1 = ns.length; k < len1; i = ++k) {
n = ns[i];
context = context[n];
}
if (typeof func !== 'function') {
throw new TypeError('Cannot execute function ' + name);
}
return func.apply(context, args);
}
为了更好的可读性检查CoffeeScript版本:
executeByName = (name, context = window) ->
args = Array.prototype.slice.call(arguments, 2)
normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.')
ns = normalizedName.split "."
func = context
for n, i in ns
func = func[n]
ns.pop()
for n, i in ns
context = context[n];
if typeof func != 'function'
throw new TypeError 'Cannot execute function ' + name
func.apply(context, args)
你只需要通过window[<方法名>]将字符串转换为指针。 例子:
var function_name = "string";
function_name = window[function_name];
现在你可以把它当做一个指针。
由于eval()是邪恶的,而new Function()不是最有效的方法来实现这一点,这里有一个快速的JS函数,从它的字符串名称返回函数。
适用于命名空间的函数 在null/undefined字符串的情况下回退到null函数 如果没有找到函数,则回退到null函数
function convertStringtoFunction(functionName){ var nullFunc = function(){}; // Fallback Null-Function var ret = window; // Top level namespace // If null/undefined string, then return a Null-Function if(functionName==null) return nullFunc; // Convert string to function name functionName.split('.').forEach(function(key){ ret = ret[key]; }); // If function name is not available, then return a Null-Function else the actual function return (ret==null ? nullFunc : ret); }
用法:
convertStringtoFunction("level1.midLevel.myFunction")(arg1, arg2, ...);
我认为你不需要复杂的中间函数或eval,也不需要依赖像window这样的全局变量:
function fun1(arg) {
console.log(arg);
}
function fun2(arg) {
console.log(arg);
}
const operations = {
fun1,
fun2
};
operations["fun1"]("Hello World");
operations.fun2("Hello World");
// You can use intermediate variables, if you like
let temp = "fun1";
operations[temp]("Hello World");
它也可以使用导入的函数:
// mode.js
export function fun1(arg) {
console.log(arg);
}
export function fun2(arg) {
console.log(arg);
}
// index.js
import { fun1, fun2 } from "./mod";
const operations = {
fun1,
fun2
};
operations["fun1"]("Hello World");
operations["fun2"]("Hello World");
因为它使用的是属性访问,所以它将在最小化或混淆中存活下来,这与您在这里找到的一些答案相反。
在我的代码中有一个非常相似的东西。 我有一个服务器生成的字符串,其中包含一个函数名,我需要作为第三方库的回调传递。所以我有一个代码,接受字符串并返回一个指向函数的“指针”,如果没有找到,则为空。
我的解决方案非常类似于“Jason Bunting的非常有用的功能”*,尽管它不能自动执行,而且上下文总是在窗口上。但这是很容易修改的。
希望这能对别人有所帮助。
/**
* Converts a string containing a function or object method name to a function pointer.
* @param string func
* @return function
*/
function getFuncFromString(func) {
// if already a function, return
if (typeof func === 'function') return func;
// if string, try to find function or method of object (of "obj.func" format)
if (typeof func === 'string') {
if (!func.length) return null;
var target = window;
var func = func.split('.');
while (func.length) {
var ns = func.shift();
if (typeof target[ns] === 'undefined') return null;
target = target[ns];
}
if (typeof target === 'function') return target;
}
// return null if could not parse
return null;
}