为什么在 JavaScript 中使用回调,它有什么优势?
回调函数基本上是函数(命名或匿名),它们作为参数传递给另一个函数的调用。
JavaScript 语法允许我们将函数视为对象,因此我们可以毫无问题地将先前定义的函数的 name 作为另一个函数的参数传递。我们也可以将匿名函数的完整代码作为参数传递,例如在表单字段验证过程的 XMLHttpRequest 响应处理程序中:
req.onreadystatechange = function()
{
if (req.readyState === 4 && req.status === 200)
{
if (req.responseText !== 'Valid') // Check for invalid field value ...
{
document.getElementById(field + 'err').value = req.responseText; // ... and output detail to error field
document.getElementById(field + 'err').style.color = 'red'; // Field comment in red
document.getElementById(field + '-errchk').innerHTML = '\u00D7'; // Cross mark opposite data field
document.getElementById(field + '-errchk').style.color = 'red'; // ... in red
document.getElementById(field + '-errchk').style.fontWeight = 800; // ... and bold
}
else
{
document.getElementById(field + 'err').value = ''; // Clear error info field
document.getElementById(field + 'err').style.color = 'green'; // Field comment in green
document.getElementById(field + '-errchk').innerHTML = '\u2713'; // Check mark opposite data field
document.getElementById(field + '-errchk').style.color = 'green'; // ... in green
document.getElementById(field + '-errchk').style.fontWeight = 800; // ... and bold
}
}
}
在 JavaScript 中,使用回调函数优于使用非回调函数(即在另一个函数中调用的函数不包含它作为参数)在于回调函数的可访问数据范围,它的 范围。
非回调函数只能访问它们自己的内部作用域、它们自己的全局作用域以及输入给它们的参数值。除此之外,他们无法单方面访问使用它们的任何代码块的范围。因此,如果我们想让一个非回调函数在调用它的代码中“看到”某些 vars/consts/functions/collections,我们需要将这些声明移到非回调函数的范围内。这总是有点麻烦,有时非常棘手。否则,我们可能需要重新定义非回调函数,以便将来自调用代码范围的其他不可共享数据作为参数传递给它。这当然会更改非回调函数的声明并影响使用它的任何其他代码块。
回调函数既可以访问它们自己的作用域,也可以访问调用它们的代码作用域以及调用代码的全局作用域。
因此,回调函数更便于管理代码,尤其是在大型 JS 应用程序中,其中数据在任务执行期间跨越多个模块边界传递。
回调函数几乎从一开始就存在于 JavaScript 中。
在 Web 应用程序的前端,您会看到它们用于事件侦听器之类的东西,例如,如果我们想要删除鼠标悬停在网页日历的“下个月”箭头之外时显示的文本:
var mouseOut = function(e)
{
if (document.getElementById("right-info").innerHTML != "")
{
document.getElementById("right-info").innerHTML = "";
}
};
nextM.addEventListener('mouseout', mouseOut, false);
在 Web 应用程序的后端,回调用于浏览器和服务器之间的异步数据传输。它们还被用作确保包含异步功能(例如数据库查询、网络调用、文件系统操作、从外部设备加载数据等)的后端 JS 脚本以所需顺序执行的原始手段。基本上,通过包含一个回调函数,该函数执行需要在异步过程之后立即完成的操作作为异步函数的参数,我们可以确保其正确排序 w.r.t。异步进程。回调函数的范围权限也有助于编码。
现在很少在后端使用回调函数,因为现代 JavaScript 包含一个 Promise 对象,该对象以更清晰和更具可扩展性的方式封装了异步进程的处理。
但是知道它们是什么以及在哪里可以有效地使用它们仍然很好。