在JavaScript中将字符串转换为函数

sh7euo9m  于 2023-01-08  发布在  Java
关注(0)|答案(5)|浏览(391)

我正在尝试使用一些Office JavaScript,并尝试从API调用接收到的字符串创建可执行函数。
Excel的office JavaScript任务窗格在单击按钮时调用外部API,并以String对象的形式返回函数。为了将其转换为函数对象,我使用了:

var executable = new Function(response)
executable();

不幸的是,什么都没有发生,它似乎根本没有调用该函数。
经过一些调试,我相信它没有被调用的原因是因为响应字符串对象已经是一个完整的函数,而新的Function()将响应 Package 在另一层函数中。
回答是:

async function highlightCells() {
    await Excel.run(async (context) => {
        const sheet = context.workbook.worksheets.getItem("Sheet1");
        const range = sheet.getRange();
        range.format.fill.color = "yellow";
        await context.sync();
        console.log("Called");
    });
}

可执行文件解析为:

function anonymous() {
  async function highlightCells() {
    await Excel.run(async (context) => {
        const sheet = context.workbook.worksheets.getItem("Sheet1");
        const range = sheet.getRange();
        range.format.fill.color = "yellow";
        await context.sync();
        console.log("Called");
    });
  }
}

你知道如何防止额外的函数 Package 器出现吗?正如你所看到的,response对象已经是一个完整的函数了。
是否需要使用其他方法将字符串转换为函数,或者是否有办法在新的Function()语法中覆盖 Package 器?

liwlm1x9

liwlm1x91#

如果事先不知道函数名,可以将函数定义括在括号中以调用它。

let response = `async function test() {
    console.log("function called");
}`;

let executable = new Function(`(${response})();`);
executable();

如果需要传递参数或等待它,让它返回函数并调用函数以获得实际函数。

let func = `async function sum(a,b) {
    return new Promise(resolve => setTimeout(() => resolve(a+b), 1000));
}`;

let executable = new Function(`return ${func};`)();
(async () => {
    let val = await executable(3,4);
    console.log("the sum is", val);
})();
dgtucam1

dgtucam12#

如果您知道它肯定是一个函数,则可以直接在Function中调用它:

let data = 'function(arg1, arg2) { return arg1 + " " + arg2 }'

let func = new Function(`return (${data}).apply(this, arguments)`)

console.log(func(1,2))

使用.apply(this, arguments),你调用那个函数,把你传递给Function对象的参数传递给received函数,return返回那个函数的结果。
this传递给apply可以确保Function对象可以存储在对象中,并且接收到的函数可以使用this访问该对象。这可能不是必需的,但会使函数的行为类似于常规函数:

let data = 'function(arg1, arg2) { return arg1 + " " + arg2 + " " + this.prop }'

let obj = {prop : 'somevalue'}
obj.func = new Function(`return (${data}).apply(this, arguments)`)

console.log(obj.func(1, 2))
b09cbbtk

b09cbbtk3#

只需使用eval而不是new Function,您需要强制代码成为表达式,而不是语句,这就是0,部分的作用。

code = `function test() {
    console.log('hey!')
}`

let executable = eval('0,' + code)

executable()
bwitn5fc

bwitn5fc4#

var executable = new Function(response + ';highlightCells()')
executable();
ijnw1ujt

ijnw1ujt5#

由于返回的代码是完整的可执行语句,因此使用eval()执行它,而不是new Function()

eval(response);
highlightCells();

注意,这需要知道响应中定义的函数名,如果不知道,就需要编写代码解析它以提取函数名。

相关问题