【问题标题】:when calling the function within itself return value is not the same in second call当在自身内部调用函数时,第二次调用中的返回值不同
【发布时间】:2014-12-25 02:56:44
【问题描述】:

我正在尝试使用 javascript 提示获取网站的用户名。如果用户按下取消,提示应该再次出现,或者如果他输入空值,提示应该再次出现。

我不希望用户在没有输入正确用户名的情况下使用该网站。为此,我编写了一个函数来检测是否输入了用户名。但它工作不正常,它第一次返回值,但如果我按取消并在第二个提示中输入值。该函数不返回任何内容。我不明白我做错了什么。

function getusername()
{
  var user = prompt("Please Enter Your Username");
  if(user == null || user == "")
  {
    getusername();
  }
  else
  {
    return user;
  }
}

当我像alert(getusername()); 这样调用它时,值第一次出现,但如果我在第一个提示中按取消并在第二个提示中输入用户名,则警报未定义。请帮我。

【问题讨论】:

    标签: javascript function


    【解决方案1】:

    其他人提到,如果您没有得到想要的输入,您会错过return

    但更一般地说,您的方法存在问题,因为它不必要地使用了recursion。通过从自身内部调用getusername(),您最终会得到一个调用堆栈,该堆栈的深度会随着您获得的无效输入的数量而增长。理论上,如果用户只是在一个空提示符下继续按回车键,那么您可以生成一个stack overflow

    有时递归非常适合解决问题,如果你不使用它,你最终会自取其辱。但这是您可能更适合使用 while 循环之类的情况的示例:

    function getusername() {
       var user = null;
       while (!user) {
           user = prompt("Please Enter Your Username");
       }
       return user;
    }
    

    无论堆栈大小如何,它都可以容忍无限数量的空白提示。还可以更轻松地控制计算输入无效输入的次数以施加限制。

    作为一个微不足道的功能,你做什么可能并不重要。保持你的思维流畅很重要,因为有些语言实际上会迫使你的手递归地制定这些事情。了解权衡是有用的。然而我想说,在 JavaScript 这样的命令式编程语言中,这是一个使用递归的糟糕选择的实例。

    【讨论】:

    • 谢谢。 HostileFork,我学到了关于 javascript 中递归的新知识。
    • @Vignesh 我想强调不要从“递归是不好的”这一点中删除。相反,它可能非常好...并且是以divide-and-conquer 的方式根据较小的子问题来构建问题的基础。但是考虑在 10 个无效的提示响应后暂停调试器...您要查看调用堆栈并查看调用 getusername 或 getusername/getusername/getusername/getusername/getusername/getusername/getusername/getusername/getusername/getusername... 的函数吗?
    • 是的,我在嵌入式 c 中使用了递归,它在那里非常有用。但我知道我没有在这段代码的完美用例中使用递归。谢谢。
    【解决方案2】:

    您的 if 分支不会返回任何内容。当一个函数不返回任何内容时,它会隐式返回undefined,因此您会发出警报。您需要从您的if 分支返回:

    function getusername()
    {
      var user = prompt("Please Enter Your Username");
      if(user == null || user == "")
      {
        return getusername();
      }
      else
      {
        return user;
      }
    }
    

    这使else 变得多余,因此您可以稍微缩短代码(请注意,我还将条件更改为!user,这应该涵盖所有可能发生的情况):

    function getusername()
    {
      var user = prompt("Please Enter Your Username");
      if(!user)
      {
        return getusername();
      }
      return user;
    }
    

    这导致了一个更短的单行:

    function getusername()
    {
      return prompt("Please Enter Your Username") || getusername();
    }
    

    【讨论】:

    • 是的。我只是注意到了这一点,并在下面更正并发布了我自己的答案。还是谢谢你。
    • ...@Vignesh 如果您在提示符下继续按回车键,您最终会出现堆栈溢出。 :-/ 为每个空白输入添加一层堆栈深度?
    • 那么有没有更好的方法@HostileFork
    • @Vignesh While 循环? “虽然我没有收集到令我满意的用户名,但继续提示”var user = null; => while (!user) { user = prompt("Please Enter Your Username"; } => return user;
    • @HostileFork 你的方式是正确的,你应该把这个作为答案发布,这样我才能接受。
    【解决方案3】:

    我通过一个小改动解决了这个问题,

    function getusername()
    {
      var user = prompt("Please Enter Your Username");
      if(user == null || user == "")
      {
        return getusername();
      }
      else
      {
        return user;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-03
      • 2010-11-29
      • 2020-10-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多