我试图将返回的函数和函数作为JavaScript中的参数包围。到目前为止,我已经看到一个或另一个被用在一个函数中,但不是两个。我有以下代码:
function adds(num, foo) {
foo();
return function(param) {
document.write("Hello ", param, "<br>");
};
}
var x = 20;
adds(x, function() {
x += 2;
})("World");
document.write(x);
//I end up getting:
//Hello World
//22
现在我的问题是,为什么返回的函数先执行?我的理解是当add();被调用它会调用foo();在返回匿名函数之前。但是,当我们查看输出时,情况并非如此。
我也明白这可能不是完成任务的最佳方式,但为了学习,我决定玩这些概念。
答案 0 :(得分:0)
在使用document.write
进行x
调用之前,您正在调用匿名函数。您可以推迟调用该函数以获得所需的结果。
var result = adds(x, function() {
x += 2;
});
document.write(x);
result("World");
答案 1 :(得分:0)
我已使用按顺序编号的注释来注释您的代码,这些注释显示了执行顺序。您会注意到document.write
返回的回调中的adds()
在最底层的回调之前被调用。
function adds(num, foo) {
foo(); // 3. Call anonymous function
// 5. Return an anonymous function that receives `param` when invoked
return function(param) {
document.write("Hello ", param, "<br>"); // 7. Write "Hello " + "World"
};
}
var x = 20; // 1. Assignment of 20 to `x`
// 2. Call `add()`, passing `20` and an anonymous function
adds(x, function() {
x += 2; // 4. Mutate `x` to add `2`. This does not affect `num` above.
}) /* 6. Invoke returned anonymous function --> */ ("World");
document.write(x); // 8. Write the current value of `x` (22) to the document
所以你是正确的,传递给foo
的匿名函数首先被调用,没有副作用让你观察到这个调用。唯一的副作用是x
的变异,但是在document.write()
之前看不到这种情况,这发生在所有其他呼叫之后。
如果您在foo
匿名函数中添加另一个日志,您将能够更清楚地看到其执行点。
adds(x, function() {
document.write("Anon func, mutating `x`" + "<br>");
x += 2;
})("World");
现在输出将是:
Anon func, mutating `x` Hello World 22
最后一点,使用console.log()
比document.write()
更适合观察运行时行为。
答案 2 :(得分:0)
在您的初始adds
功能
function adds(num, foo) {
// this occurs on the initial function call, inside the scope of the adds function and does not carry over into the returned function.
foo();
// returning your function for later use, this will print 'hello' plus your passed in param.
return function(param) {
document.write("Hello ", param, "<br>");
};
}
// set your initial var
var x = 20;
// execute
adds(x/*20*/, function() {\
// does not relate to the num param inside the adds function for the return
x/*20*/ += 2;
})("World");
您的执行顺序已关闭,为了清晰起见,我已经解决了一些问题
const adds = (number, callback) => {
return param => {
// using callback within scope of returned function
let x = callback(number);
document.write(`Hello ${x} ${param}`);
}
};
let x = 20;
let callbackFunc = amount => (amount + 2);
let results = adds(x, callbackFunc);
对于稍微更实用的真实世界返回功能,我经常在需要进行一些设置以使回调准备就绪的地方使用它们。这允许您在安装过程中注入依赖项,而不必将它们包含在整个地方。 (有助于解耦测试和组织)
module.exports = function(db,logger) {
return async (req, res) => {
let result = await db.findOne(/* stuff */);
if (result.length === 0) {
logger.error('stuff not found');
res.sendStatus(404);
}
// do some processing, or not.
res.send(result);
};
};