JavaScript函数,返回undefined。

4

大家好,希望你们都过得很好。

这是我的代码,有一个叫做“function”的函数,它带有名称和回调函数,将名称传递给回调函数以返回名称并在控制台上记录它。

如果我

function doSomething(name,callback) {
    callback(name);
}

function foo(n) {
    return n;
}

var val = doSomething("TEST",foo);
console.log(val);

我得到了未定义的结果。

如果我

function doSomething(name,callback) {
    callback(name);
}

function foo(n) {
    console.log(n);
}

var val = doSomething("TEST",foo);

代码本应正常运行并在控制台输出TEST名称,但是为什么返回值没有起作用呢?

谢谢。


就像它所说的那样。在这两段代码中,doSomething 都没有返回任何内容(但是如果在 n 变量处于作用域时使用 console.log,它将被记录)。你是不是想要返回 doSomething() - CertainPerformance
1
return callback(name); - JohanP
我希望foo函数返回n; - Obeid
是的,让foo返回n并使doSomething return callback(name) - JohanP
4个回答

5

您的 doSomething() 函数没有返回任何值,这意味着使用它进行赋值将会是 undefined。但实际问题不在于此。

根本的问题是您似乎混合了两种不同的数据处理模式:如果您编写纯同步代码,则使用返回函数(立即返回某个值)。如果您需要异步代码,则使用回调函数(将“最终”执行某些操作)。混合这两个模式会导致问题和沮丧:

要么:

  1. 不要将您的函数命名为“回调”,并让它返回其已处理的值,或者
  2. 使回调负责执行您要使用 val 做的任何事情。

情况 1:

function doSomething(data, processor) {
  return processor(data);
}

function passThrough(v) { return v; }

var val = doSomething("test", passThrough);
// immediately use "val" here in for whatever thing you need to do.

案例2:
function doSomething(data, callback) {
  // _eventually_ a callback happens - for instance, this
  // function pulls some data from a database, which is one
  // of those inherently asynchronous tasks. Let's fake that
  // with a timeout for demonstration purposes:
  setTimemout(() => callback(data), 500);
}

function handleData(val) {
  // use "val" here in for whatever thing you need to do. Eventually.
}

doSomething("test", handleData);

如果您想选择方案2,您真的需要了解现代JavaScript中的“Promises”和async/await,这些是基于“一旦有要回调的内容就进行回调”的思想而高度改进的方法。
2021年更新:自原始编写此答案以来的第三个选项是使用async/await模式,它是Promise周围的语法糖。
方案3:
async function doSomething(input) {
  // we're still _eventually_ returning something,
  // but we're now exploiting `async` to wrap a promise,
  // which lets us write normal-looking code, even if what
  // we're really doing is returning a Promise object,
  // with the "await" keyword auto-unpacking that for us.
  return someModernAsyncAPI.getThing(input);
}

function handleData(val) {
  // ...
}

async function run() {
  const data = await doSomething("test");
  handleData(data);
}

run();

我仍然建议学习现代 JS 写异步代码的方式,即使您的代码“没有必要是异步的”。JS 运行在单线程中,任何需要很长时间的操作都会阻塞线程,包括任何事件处理程序,因此通常您总是希望编写异步代码,以确保代码中有足够的点,让任务调度程序可以简短地将控制权移交给其他需要运行的事物。 - Mike 'Pomax' Kamermans
好的,我只想使用XMLHttpRequest和调用函数,调用函数将具有responseText。 - Obeid
你可能不想使用那个,因为它是一种相当古老的机制,并需要有效过时的JS方法。相反,你应该使用现代的Fetch API,这是一种非常明确的异步、现代化的JS获取远程内容的方式。请参见https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch - Mike 'Pomax' Kamermans
我刚刚完成了收藏产品的功能,如果用户点击了收藏图像,就会调用XMLHttpRequest并将其插入到数据库中。 - Obeid

2
function doSomething(name,callback) {
callback(name);
}

function foo(n) {
   console.log(n);
   return n;
}

var val = doSomething("TEST",foo);

请看上面的代码。当您调用doSomething时,它会在内部执行foo并打印到控制台,因为这就是console.log的作用。但是,在此语句之后,它也返回n,然后在doSomething中接收。但它没有被返回。简而言之,您主要正在做的是

function doSomething(name,callback) {
    const returnValue = callback(name);
}

如果您调用上述方法,它将返回undefined。为了使其返回正确的值,您必须调用"return returnValue"。同样,您必须说 "return callback(name)"。
希望这可以帮助您。
愉快的学习。

0
为了给函数返回的值/对象(在这种情况下是doSomething)分配一个赋值语句,它应该有一个返回语句。否则,函数将返回空值,因此当您将其分配给val时,它仍然是undefined
所以你需要修改你的代码像这样:
function doSomething(name,callback) {
    return callback(name);
}
function foo(n) {
    return n;
}
var val = doSomething("TEST",foo);
console.log(val);

0
如果在函数中没有使用 return 关键字,则会隐式返回 undefined。
当调用 var val = doSomething("TEST",foo) 时,你将 doSomething 的返回值赋值给了变量 val,但是由于函数里面没有显式的 return 语句,所以 val 的值为 undefined。
function doSomething(name,callback) {
  return callback(name);
}

function foo(n) {
  return n;
}

var val = doSomething("TEST",foo);
console.log(val);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接