开发者问题收集

关于 JavaScript 计算总和程序的异常浏览器错误和建议

2018-05-04
171

所以我有一道课堂问题:

计算总和

创建一个名为 calculateSums 的函数,该函数将接受一个数字数组,如果所有正数的总和大于或等于所有负数的绝对值的总和,则返回 true。

完成方法

  • 您应该在解决方案中使用 while 循环。
  • 无论您将 0 视为正数还是负数,都没有关系,因为它不会改变任何一边的总和。
  • 循环完成后,您应该只返回正数的总和是否大于或等于负数的总和。
  • 应该可以按如下方式调用该函数:

    calculateSums([-1,2]) 返回 true

    calculateSums([-1,2,-3]) 返回 false

在您的代码中,多次调用您的函数并在 HTML 页面上显示使用的数组和结果。

我无法弄清楚如何使用 while 循环来执行此操作。我有一个,但它不对。我还尝试使用 "document.getElementByID("message").innerHTML..." 显示结果,但出现了无法理解的错误。

这是我的代码:

/**
* This function calculates the absolute sum of an array of numbers
* @inputs a - an array of numbers
* @returns compare - a boolean
*/
        function calculateSum(a) {

            //declare variables and set them equal to 0.
            var result = 0;
            var possum = 0;
            var negsum = 0;
            var compare;
            while (possum >= negsum) {
                for (var i = 0; i < a.length; i++) {
                    var num = a[i];
                    result = result + Math.abs(num);
                    if (num%2 == 0) {
                        possum += result;
                    } else {
                        negsum += result;
                    }
                    result = 0;
                }
                if  (negsum > possum) {
                    compare = false;
                    break;
                } else {
                    compare = true;
                    break;
                }
            }
            if (compare == true) {
                document.getElementById("message").innerHTML = compare;
            } else {
                document.getElementById("message").innerHTML = compare;
            }
        return compare;
        }

这是我的 HTML:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Calculate Sums</title>
    <script src = "assignment3.js"></script>
</head>
<body>

    <script>
        calculateSum([-1,2,3,-2]);
        calculateSum([-3,1,-5,2]);
    </script>
    <p id = "message"></p>

</body>
</html> 

我希望有人能帮助我理解这个错误,并提供更好的方法建议。

这是浏览器中的错误:

Uncaught TypeError: Cannot set property 'innerHTML' of null
    at calculateSum (assignment3.js:34)
    at calculateSums.html:12

我对编码还很陌生,因此经常感到沮丧。我非常感谢在这个网站上找到的帮助。

更新:我找到了如何修复 while 语句的方法。

while (possum >= negsum || negsum > possum) 

我不确定这是否正是我的老师想象的那样,因为我们还有这些验收标准:

计算总和

  1. 您的代码必须包含一个名为 calculateSums 的函数,该函数接受 数字数组并包含一个返回语句
  2. 您的函数必须包含一个 while 循环。
  3. 您的代码必须使用 Math.abs() 来获取任何 负数的绝对值。
  4. 您的代码不得包含无限循环。
  5. 您的代码必须有条件地返回 true 或 false。
  6. 您的代码必须包含多种测试变体以显示您的 函数有效。
3个回答

您的代码中存在的主要问题如下:

当浏览器收到代码中的 HTML 标记时,它会从上到下进行处理。

因此,根据您分享的代码,代码将按以下顺序执行:

由于 head 部分位于顶部,因此会首先加载。因此,您的外部脚本 assignment3.js 也会被加载。 (现在脚本中的函数在全局命名空间中可用)

<head>
    <meta charset="UTF-8" />
    <title>Calculate Sums</title>
    <script src = "assignment3.js"></script>
</head>

然后浏览器转到正文

<body>

    <script>
        calculateSum([-1,2,3,-2]);
        calculateSum([-3,1,-5,2]);
    </script>
    <p id = "message"></p>

</body>

首先,执行脚本标记

    <script>
        calculateSum([-1,2,3,-2]);
        calculateSum([-3,1,-5,2]);
    </script>

直到 calculateSum 函数中的这一行,此过程都正常

document.getElementById("message").innerHTML = compare;

因为此时,浏览器尚未开始呈现 <p> 标记(脚本在此之前出现并执行)。因此 document.getElementById("message") 找不到 p 标记,最终不返回任何内容(null)。当您尝试访问 null 上的属性时,您会收到此错误 无法设置 null 的属性“innerHTML”

因此,要修复此问题(并且作为一般最佳实践),最好将脚本放在 body 标记的末尾,如下所示(而不是放在头部):

<body>
    <p id = "message"></p>
    <script src = "assignment3.js"></script>
    <script>
        calculateSum([-1,2,3,-2]);
        calculateSum([-3,1,-5,2]);
    </script>
</body>

这可确保您的页面加载不会被脚本阻止,并且还会产生副作用,即在执行代码时 DOM 已呈现并准备就绪。

具体到您的分配问题,您可以使用 while 循环遍历数组并以简单的方式解决它。

一些更改说明:

  1. 将 DOM 操作移出 calculateSum 方法。此方法现在具有一个明确的目的,即计算总和并返回 true 或 false。
  2. 编写一个新函数 runTestCases ,该函数基本上为我们要运行的不同测试创建一个数组数组,并为每个测试运行 calculateSum 方法。它还会更新 DOM 以反映问题陈述中所述的结果。
  3. 使用 while 循环在 calculateSum 中迭代数组>
/**
 * This function calculates the absolute sum of an array of numbers
 * @inputs a - an array of numbers
 * @returns compare - a boolean
 */
function calculateSum(a) {

  //declare variables and set them equal to 0.
  var result = 0;
  var possum = 0;
  var negsum = 0;
  var currentIndex = 0;

  while (currentIndex < a.length) {
    var e = a[currentIndex++];
    if (e < 0) {
      // Negative number
      negsum += Math.abs(e);
    } else {
      // Positive number
      possum += e;
    }
  }

  return possum >= negsum;
}

function runTestCases() {
  // Array of test cases. (You can add or remove tests as needed)
  var tests = [
    [-1, 2],
    [-1, 2, -3]
  ];

  // Get reference of the list element to show the results
  var ul = document.getElementById("result");

  // Iterate over the tests aray and update dom to show each result
  for (var i = 0; i < tests.length; i++) {
    var test = tests[i]; // Get the current test case
    var result = calculateSum(test); // Get the result

    // Create a new DOM element to display the result
    var li = document.createElement('li');
    li.innerHTML = JSON.stringify(test) + " <b> " + result + "</b>";

    //Appenf newly created element to the list
    ul.append(li);

  }
}

runTestCases();
<div>
  <ul id="result"></ul>
</div>
Chirag Ravindra
2018-05-04

这是我认为涵盖所有要求的答案:

function calculateSums(nums) {
    var posSum = 0,
        negSum = 0,
        i = 0,
        num;

    while (i < nums.length) {
        num = nums[i];

        if (num < 0) {
            negSum += Math.abs(num);
        } else {
            posSum += num;
        }
        ++i;
    }
    return posSum >= negSum;
}
Evan Trimboli
2018-05-04

Uncaught TypeError: Cannot set property 'innerHTML' of null at calculateSum (assignment3.js:34) at calculateSums.html:12

您必须在 p 标签后调用 calculateSum() 函数。它会尝试在声明之前分配值。请将您的脚本放在标签之前。

n41tik
2018-05-04