错误传播
不幸的是,程序员不可能避免所有问题。 如果你的程序以任何方式与外部世界进行通信,则可能会导致输入格式错误,工作负荷过重或网络故障。
如果你只为自己编程,那么你就可以忽略这些问题直到它们发生。 但是如果你创建了一些将被其他人使用的东西,你通常希望程序比只是崩溃做得更好。 有时候,正确的做法是不择手段地继续运行。 在其他情况下,最好向用户报告出了什么问题然后放弃。 但无论在哪种情况下,该程序都必须积极采取措施来回应问题。
假设你有一个函数promptInteger
,要求用户输入一个整数并返回它。 如果用户输入"orange"
,它应该返回什么?
一种办法是返回一个特殊值,通常会使用null
,undefined
或 -1。
function promptNumber(question) {
let result = Number(prompt(question, ""));
if (Number.isNaN(result)) return null;
else return result;
}
console.log(promptNumber("How many trees do you see?"));
现在,调用promptNumber
的任何代码都必须检查是否实际读取了数字,否则必须以某种方式恢复 - 也许再次询问或填充默认值。 或者它可能会再次向它的调用者返回一个特殊值,表示它未能完成所要求的操作。
在很多情况下,当错误很常见并且调用者应该明确地考虑它们时,返回特殊值是表示错误的好方法。 但它确实有其不利之处。 首先,如果函数已经可能返回每一种可能的值呢? 在这样的函数中,你必须做一些事情,比如将结果包装在一个对象中,以便能够区分成功与失败。
function lastElement(array) {
if (array.length == 0) {
return {failed: true};
} else {
return {element: array[array.length - 1]};
}
}
返回特殊值的第二个问题是它可能产生非常笨拙的代码。 如果一段代码调用promptNumber
10 次,则必须检查是否返回null
10 次。 如果它对null
的回应是简单地返回null
本身,函数的调用者将不得不去检查它,以此类推。