【问题标题】:Why am I getting undefined instead of null?为什么我得到 undefined 而不是 null?
【发布时间】:2021-04-21 16:41:26
【问题描述】:

我写了一个函数,它返回一个给定数字(1 = 星期一,2 = 星期二等)的星期几,我应该创建一个警告,如果数字小于 1 或大于 7,函数应该返回 null。为什么它会为 0 和 8 返回 undefined?

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

function returnDay(day) {
  day = daysOfWeek[day - 1];
  if (day > 7 || day < 1) {
    return null
  } else {
    return day
  }
}

console.log(returnDay(8))
console.log(returnDay(0))

【问题讨论】:

  • 也许索引day - 1处的daysOfWeek项未定义?能否分享一个调用函数的示例以及daysOfWeek 的示例?
  • 请在问题中添加daysOfWeek
  • day = daysOfWeek[day-1]; 您正在覆盖day,因此在此之后它将不再是一个数字。因此,在此之后的在线检查不会像您期望的那样工作。
  • 在检查输入是否有效之前,您正在重新分配给day
  • 记下你在函数中做的第一件事,before if

标签: javascript arrays function null


【解决方案1】:

您正在覆盖您的论点,这被认为是不好的做法。

当您访问daysOfWeek[0 -1] => daysOfWeek[-1] => undefined 时,您评估的是undefined &lt; 1,即falsy。所以你输入 else,它返回 day => undefined

以下代码有效

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

function returnDay(day) {
  if (day <= 7 && day >= 1) {
    return daysOfWeek[day - 1]
  }
  return null
}

console.log(returnDay(8))
console.log(returnDay(0))

或者,甚至更密集

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

function returnDay = d => daysOfWeek[d - 1] || null

console.log(returnDay(8))
console.log(returnDay(0))

【讨论】:

  • 这里有同样的问题。如果daysOfWeek 大小因某种原因发生变化怎么办?您必须在代码中调整两件事,而不是一件。是的,OP给出的答案中刚刚给出了另一个好点。
  • 另外注意,当你有多个变量代表一个相似的概念时,它有助于在变量名中区分它们。在这种情况下,'dayIndex' 和 'dayTitle` 会很好地工作,它有助于避免您在这里遇到的头痛
  • @raina77ow 我预计一周中的日子不会很快改变。但是原则上你是正确的,最好参考daysOfWeek.length。就此而言,这是可行的,但为什么它适用于初学者就不太明显了。 day =&gt; daysOfWeek[day-1] || null
  • 它可以工作,因为它会尝试获取给定日期的标题 - 如果获取失败,则会给出默认值。这是尽可能简单的。根据定义,检查范围很容易出错; OP的帖子中刚刚给出了一个示例。
  • 在这一点上我们正在分心,但我不认为短路评估是教导新开发人员的最佳方式。也许你认为是,那很好。
【解决方案2】:

基本上,您的代码中现在有两个范围检查,这是最大的问题。

这是第一个检查:

day = daysOfWeek[day - 1];

... 以undefined 结尾,除非day 具有有效值(因此daysOfWeek 中有一个元素对应于该值)。

这是第二次检查:

if (day > 7 || day < 1) { ... }

... 最终会做错事,因为 day 变量在第一次检查的那一行中获得了不同的值。当然,您可以通过引入另一个名称来解决此问题...

const dayTitle = daysOfWeek[day - 1];
if (day > 7 || day < 1) { ... }

...但这意味着您仍在检查相同的条件两次。重复自己永远不是一个好主意。

下面是如何做到的:

function returnDay(day) {
  return daysOfWeek[day - 1] || null;
}

... 是的,就这么简单:边界范围检查现在由 JS 完成,而不是您和您的代码。换句话说,如果day 值不能用作该dayOfWeek 数组的正确索引,那么您只会得到undefined(它将由|| null 合并到,嗯,null)。

是的,在这种情况下将null 作为默认值对我来说似乎很奇怪。

【讨论】:

    【解决方案3】:

    所以我改变了论点,所以那一天不再被覆盖,它看起来像这样:

    function returnDay(n){
        day = daysOfWeek[n-1];
        if (n  > 7 || n  < 1){
            return null
        } else {
            return day
        }
    }
    console.log(returnDay(8))
    console.log(returnDay(0))
    

    我现在成功地为 returnDay(0) 和 returnDay(8) 获取 null

    【讨论】:

    • JS 中的索引以 0 开头,而不是 1; day[7] 没有元素。但这实际上是明确检查范围不好的另一个好处。
    • 其他两个答案都更好,因为它们解释了发生了什么以及为什么应该改变它。 - 请记住,SO 在这里不仅仅是为了帮助您,而是为了帮助其他有类似问题的人。