开发者问题收集

在 IF 函数中使用 OR 运算符时,比较条件的顺序是否重要?

2020-05-30
1239

我试图更好地理解 IF 语句中的条件。当我更改条件的顺序时,我收到未定义的 TypeError。

当顺序更改为:

if (col === maze[row].length || row < 0 || col < 0 || row === maze.length) {
    return
}

在 IF 函数中使用 OR 运算符时,比较的顺序是否重要?当顺序不同时,是什么导致了 TypeError

工作代码库:

const maze = [
  [' ', ' ', ' ', '*', ' ', ' ', ' '],
  ['*', '*', ' ', '*', ' ', '*', ' '],
  [' ', ' ', ' ', ' ', ' ', ' ', ' '],
  [' ', '*', '*', '*', '*', '*', ' '],
  [' ', ' ', ' ', ' ', ' ', ' ', 'e'],
];

const solve = (maze, row = 0, col = 0, path = "") => {

  if (row < 0 || col < 0 || row === maze.length || col === maze[row].length) {
    return
  }

  // Base case
  if (maze[row][col] === "e") {
    return console.log(`Solved at (${row}, ${col})! Path to exit: ${path}`)

    // General case
  } else if (maze[row][col] === "*") {
    return
  }

  // Marker
  maze[row][col] = "*"

  // Right
  solve(maze, row, col + 1, path.concat("R"))

  // Down
  solve(maze, row + 1, col, path.concat("D"))

  // Left
  solve(maze, row, col - 1, path.concat("L"))

  // Up
  solve(maze, row - 1, col, path.concat("U"))

  // Remove marker
  maze[row][col] = " "
}

console.log(solve(maze));
2个回答
622224841

是的,除了操作员优先级外,您还需要查看 cossociativity 短路评估 || 运算符具有 从左到右的关联性,这意味着它将从左到右评估表达式。短路评估意味着一旦已知结果,就会忽略进一步的逻辑条件。

681397062

查看您的状况:

163492772

由于从左到右评估逻辑操作,因此要评估的第一个是 col ===迷宫[row] .length 。当 行=== Maze.length ,然后 col ===迷宫[row] .length 评估 col ==== undefined.length.length.length.length ,这当然会产生错误。

要解决此问题,您需要在 首先确认该索引不会是未限制的。一种简单的方法是:

065142668

现在,如果前三个条件中的任何一个是 true ,则JavaScript不会打扰评估该评估休息,因为它已经知道结果是 true 。因此,它不再崩溃了。

(请记住 true || false === true ,因此一旦看到 true | true | | 那么,您甚至不需要阅读其余的表达式即可知道结果将为 true 。)


请注意,如果您正在使用一种不使用短路评估的语言,然后,如果 语句以正确的顺序运行条件,则必须使用多个 366367405

我经常发现自己启动这样的代码,而我仔细考虑了需要进行检查的顺序,然后然后将其简化为单个表达式。<<<<<<<<<<<< /p>


希望有帮助!

Sam
2020-05-30

您需要记住两件事。

  1. Javascript 求值是从左到右的。
  2. OR || 运算符是短路。这意味着第一次遇到真表达式时,它会“短路”,即绕过所有其他表达式并只返回真。这是基本的布尔代数。

关于您对 TypeError: Cannot read property 'length' of undefined 的疑问, maze[row]maze 都是未定义的。运行您的代码片段后发现, maze[row] 是罪魁祸首。这可能是因为您执行了 row-1 ,代码中的 row 可能会变为负数,从而导致 maze[row] 未定义。

如果您将顺序改为

if (row < 0 || col < 0 || col === maze[row].length || row === maze.length) {
    return
  }

只要 row < 0 即负数,OR 运算就会使所有其他表达式短路。因此, maze[row].length 永远不会被求值,也不会遇到未定义的行为。

psychnaut
2020-05-30