Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有人能告诉我这个try-catch块(未定义的变量)有什么问题吗?(选择性捕捉,JS)_Javascript_Exception Handling_Try Catch - Fatal编程技术网

Javascript 有人能告诉我这个try-catch块(未定义的变量)有什么问题吗?(选择性捕捉,JS)

Javascript 有人能告诉我这个try-catch块(未定义的变量)有什么问题吗?(选择性捕捉,JS),javascript,exception-handling,try-catch,Javascript,Exception Handling,Try Catch,我正在读第八章。我遇到了一个关于错误代码的例子,但我仍然不理解作者对失败原因的解释。让我们给出上下文:在“”部分,作者说: 语言的无效使用,例如引用不存在的 变量,查找null上的属性,或调用 不是函数,也会导致引发异常。这样的 异常可以像您自己的异常一样被捕获 当一个捕获体进入时,我们所知道的只是我们尝试中的某些东西 身体引发了一个异常。但我们不知道是什么,也不知道是哪个例外 它导致了 JavaScript(相当明显的省略)没有提供直接的 支持选择性捕获异常:要么捕获所有异常 或者你什么也抓不

我正在读第八章。我遇到了一个关于错误代码的例子,但我仍然不理解作者对失败原因的解释。让我们给出上下文:在“”部分,作者说:

语言的无效使用,例如引用不存在的 变量,查找null上的属性,或调用 不是函数,也会导致引发异常。这样的 异常可以像您自己的异常一样被捕获

当一个捕获体进入时,我们所知道的只是我们尝试中的某些东西 身体引发了一个异常。但我们不知道是什么,也不知道是哪个例外 它导致了

JavaScript(相当明显的省略)没有提供直接的 支持选择性捕获异常:要么捕获所有异常 或者你什么也抓不到。这使得我们很容易假设 你得到的例外是你写作时正在思考的那个 挡块

但可能不是这样。其他一些假设可能会被违反,或者你 可能在某个地方引入了导致异常的bug。 下面是一个例子,它试图继续调用promptDirection 在得到有效答案之前:

for(;;)构造是一种有意创建循环的方法,该循环 不会自行终止。只有当一个 给出了有效的方向。但是我们拼错了promptDirection 将导致“未定义变量”错误因为捕捉块 完全忽略其异常值(e),假设它知道 问题是,它错误地将变量错误视为指示错误 输入。这不仅会导致无限循环,还会“掩埋” 有关拼写错误的变量的有用错误消息

我想我没有得到解释,因为英语不是我的母语。我不明白的是粗体的句子。我不明白为什么catch块会忽略变量e和关于错误输入的事情。catch块是否假定e是错误输入


有人能给我澄清一下吗。提前感谢。

这里的假设是,
promptDirection
在其正常操作中,当其输入无效时,有时会引发错误。此代码应该捕获在无效输入上引发的错误。想象一下,它是这样的:

function promptDirection(text) {
    var value = prompt(text);
    if(value != "up" && value != "down") { 
        throw new Error("not a valid direction");
    }
    return value;
}
但是,
promptDirection
此处被拼错为
promptDirection

但是我们拼错了promptDirection,这将导致“未定义变量”错误

因此,代码总是会引发错误,而这不是假设作者的意图(即,仅在无效输入时才会引发错误)

您可以使用
e
测试预期的错误类型:

catch(e) {
    if(e.message == "not a valid direction") {
        console.log("Not a valid direction. Try again.");
    } else {
        console.log("Something else went wrong:" + e.message);
    }
}

作者并不是说JavaScript总是忽略
e
;他正在谈论这个具体的例子。此示例代码编写得很糟糕(故意):

我们捕获一个异常(称为
e
),但我们从不试图找出异常的类型。我们总是,总是,说“不是一个有效的方向,再试一次。”


这段代码假设只有一件事情可能出错:输入无效。

作者试图说明的一点是,如何设置错误处理很重要。让我们假设,在程序中构建错误处理的目标之一是使错误出现时更容易捕获和解决

如果是这样的话,那么作者在这里要说明的是,这是一个错误处理的例子,它隐藏了真正的问题,使bug变得更加困难

它是如何隐藏问题的?如果你看那里的代码,它很好地建立了一个
try
块。但是在
catch
语句中,它不必检查捕获了什么类型的错误。它只是假设抛出的错误总是与无效方向相关

但事实并非如此!因为正如作者告诉您的,函数名实际上拼写错误,这将触发“undefined variable”错误。但是,由于catch块不必检查error
e
的属性,因此用户永远不会知道这就是发生的错误。相反,他们总是会看到“不是一个有效的方向,请再试一次。”但在出现“未定义变量”错误的情况下,这实际上是错误的。问题不是源于错误的用户输入,而是源于代码本身!事实上,这个例子特别糟糕,因为编码器的错误看起来像是用户错误

那么,我们如何以正确的方式做到这一点呢?嗯,有很多方法。最简单的方法是让控制台的输出指示抛出的错误,如下所示:

for (;;) {
  try {
    var dir = promtDirection("Where?"); // ← typo!
    console.log("You chose ", dir);
    break;
  } catch (e) {
    console.log(e.name, ': ', e.msg);
  }
}
更好的是,假设我们的
promptDirection
函数可以抛出一个自定义错误,如下所示:

function InvalidDirectionError(message) {
  this.name = 'InvalidDirectionError';
  this.message = message || 'Not a valid direction. Try again.';
  this.stack = (new Error()).stack;
}
InvalidDirectionError.prototype = Object.create(Error.prototype);
InvalidDirectionError.prototype.constructor = InvalidDirectionError;
然后在我们的捕获声明中,我们可以做:

for (;;) {
  try {
    var dir = promtDirection("Where?"); // ← typo!
    console.log("You chose ", dir);
    break;
  } catch (e) {
    if (e.name == 'InvalidDirectionError') {
      console.log(e.msg);
    } else {
      console.log(e.name, ': ', e.msg);
    }
  }
}

我希望这有帮助。如果需要进一步澄清,请发表评论。

我认为解释假设函数
promptDirection()
在键入的输入无效时会显式抛出异常。因此,从
try
块引发的异常可能是由于无效的输入,或者是由于意外的原因,比如函数名中的输入错误。
catch
块不会检查异常(
e
),因此,即使用户实际上根本没有机会键入,它的行为也会让用户感觉好像键入了错误的内容。谢谢,伙计,现在好多了!谢谢,你的解释帮助我理解了它!而且,现在我明白了,最好试试抓块!你是答案,答案来自t
function InvalidDirectionError(message) {
  this.name = 'InvalidDirectionError';
  this.message = message || 'Not a valid direction. Try again.';
  this.stack = (new Error()).stack;
}
InvalidDirectionError.prototype = Object.create(Error.prototype);
InvalidDirectionError.prototype.constructor = InvalidDirectionError;
for (;;) {
  try {
    var dir = promtDirection("Where?"); // ← typo!
    console.log("You chose ", dir);
    break;
  } catch (e) {
    if (e.name == 'InvalidDirectionError') {
      console.log(e.msg);
    } else {
      console.log(e.name, ': ', e.msg);
    }
  }
}