gpt4 book ai didi

javascript - 如何检测函数是否是最后一个被调用的

转载 作者:行者123 更新时间:2023-11-30 20:36:15 24 4
gpt4 key购买 nike

我必须使用加法、减法、cnst(代表常量)或带有一个或两个参数的变量等函数来创建数学表达式的求值器,具体取决于我们需要哪种运算:一元或二元。这是我正在谈论的示例:

let expression = add(cnst(2), add(cnst(2), variable("x")));

Expression 必须是一个函数,所以我们可以调用 expression(3) 并得到我们的结果:7。

我的想法是返回数字或变量的字符串表示形式(如果它是关于常量或变量的),如果它是关于二元运算的则返回第一个参数、操作和第二个参数的字符串串联。但是,我们需要使结果成为一个函数。所以,我认为返回一个函数会很好:

evaluate(x) {
return eval(expr);
}

如果此调用是最后一次调用。我的意思是,在上面的示例中,所有内部函数都应返回“2”、“2”、“x”、“2+x”,但外部函数 (add) 应返回“evaluate”并将全局值“expr”设置为在这种情况下需要什么('2+2+x')。那么,是否可以检测是否在所有其他函数之后调用了外部“添加”?

最佳答案

这有点棘手,但是如果您使用 Object.defineProperty() 重新定义一个函数的预期 arguments.length,您可以在每个级别返回一个函数并检查它的长度值来确定操作数是否需要变量:

function consume(vars) {
return (arg) => arg(...vars.splice(0, arg.length));
}

function op(f) {
return (...args) => {
return Object.defineProperty((...vars) => {
return f(...args.map(consume(vars)));
}, 'length', {
value: args.reduce((a, b) => a + b.length, 0)
});
};
}

const add = op((a, b) => a + b);
const sub = op((a, b) => a - b);
const cnst = (v) => () => v;
const variable = () => (v) => v;

let e1 = add(cnst(2), add(cnst(2), variable("x")));
let e2 = add(cnst(5), sub(variable("x"), variable("y")));

console.log(e1(5)); // 2 + (2 + 5)
console.log(e2(6, 3)); // 5 + (6 - 3)

缺点是您不能使用这种方法通过标签指定参数。为此,您可以将对象作为参数传递给表达式:

const op = (f) => (...args) => (o = {}) => f(...args.map(arg => arg(o)));

const add = op((a, b) => a + b);
const sub = op((a, b) => a - b);
const cnst = (v) => () => v;
const variable = (label) => (o) => o[label];

let e1 = add(cnst(2), add(cnst(2), variable("x")));
let e2 = add(cnst(5), sub(variable("x"), variable("y")));

console.log(e1({ x: 5 })); // 2 + (2 + 5)
console.log(e2({ x: 6, y: 3 })); // 5 + (6 - 3)

最后,如果你想要一个互操作,你可以像普通的那样为函数指定参数并将它们映射到变量名,你可以添加另一个名为 args() 的表达式类型来定义映射像这样:

const op = (f) => (...args) => (o = {}) => f(...args.map(arg => arg(o)));

const args = (map) => (e) => (...args) => e(map(...args));
const add = op((a, b) => a + b);
const sub = op((a, b) => a - b);
const cnst = (v) => () => v;
const variable = (label) => (o) => o[label];

let a1 = args(x => ({ x }));
let e1 = a1(add(cnst(2), add(cnst(2), variable("x"))));

let a2 = args((x, y) => ({ x, y }));
let e2 = a2(add(cnst(5), sub(variable("x"), variable("y"))));

console.log(e1(5)); // 2 + (2 + 5)
console.log(e2(6, 3)); // 5 + (6 - 3)

关于javascript - 如何检测函数是否是最后一个被调用的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49812713/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com