我使用的是纯 JavaScript,但我继续收到以“不是函数”结尾的错误。如何做到这一点,以便我可以检测单词并做出相应的回复?

Posted

技术标签:

【中文标题】我使用的是纯 JavaScript,但我继续收到以“不是函数”结尾的错误。如何做到这一点,以便我可以检测单词并做出相应的回复?【英文标题】:I'm using pure JavaScript but I continue to get errors that end with "is not a function". How do make it so I can detect words and reply accordingly? 【发布时间】:2021-10-28 16:59:31 【问题描述】:

我想在用户输入的文本中检测一个或多个特定的单词并做出相应的回复。我计划添加更多单词来检测,但现在我一直在使用它。 我的结果是 finalKey.contains 不是函数。

<html>
<div>
  <p1 id="iOut">????</p1>
</div>
<div>
  <input id="uIn" value=""></input>
</div>
<button onclick="regis()">SUBMIT</button>

<script>
  var key = document.getElementById("uIn").value;
  var finalKey = key.toUpperCase();

  function regis() 
    if (finalKey.contains("Hi" || "H")) 
      document.getElementById("iOut").innerHTML = "HEY";

     else if (finalKey.contains("Bye" || "Goodbye")) 
      document.getElementById("iOut").innerHTML = "Okay";

     else 
      document.getElementById("iOut").innerHTML = "???? Try again";
    
  
</script>

</html>

【问题讨论】:

另外,在 regis 函数中添加finalKey 【参考方案1】:

没有包含这样的东西。它是.includesindexOf != -1

您的值收集也需要在函数内部

另外你不能在一个语句中测试两个值,除非你把它转过来使用一个数组:

["Hi","H"].indexOf(finalKey) !=-1 

["HI","H"].filter(text => finalKey.startsWith(text)).length > 0

如果您希望 finalkey 以任何一个开头 - 如果您想测试完整的输入,请使用 .includes

最后你把文本大写了,所以比较大写文本

function regis() 
  var key = document.getElementById("uIn").value;
  var finalKey = key.toUpperCase();

  if (["HI","H"].filter(text => finalKey.includes(text)).length > 0) 
    document.getElementById("iOut").innerHTML = "HEY";
   else 
    if (["BYE","GOODBYE"].filter(text => finalKey.includes(text)).length > 0) 
    document.getElementById("iOut").innerHTML = "Okay";
   else // GOOD has to be AFTER GOODBYE to not catch it
    if (["GOOD","GREAT"].filter(text => finalKey.includes(text)).length > 0) 
    document.getElementById("iOut").innerHTML = "That's Good";
   else 
    document.getElementById("iOut").innerHTML = "? Try again";
  
<div>
  <p1 id="iOut">?</p1>
</div>
<div>
  <input id="uIn" value="" />
</div>
<button type="button" onclick="regis()">SUBMIT</button>

使用正则表达式和单词边界

注意我是用表格包裹的,现在你也可以直接回车

const wordList = [
   list: ["HI", "H"], answer: "HEY" ,
   list: ["BYE", "GOODBYE"], answer: "Okay" ,
   list: ["GOOD", "GREAT"], answer: "That's good" 
];

const defaultText = "? Try again";

document.getElementById("inputForm").addEventListener("submit", e => 
  e.preventDefault()
  const input = document.getElementById("uIn").value.trim().toUpperCase();
  let result = wordList
    .filter(( list, answer ) => list
      .filter(word => new RegExp("\\b" + word + "\\b").test(input))
      .length > 0);
      
  console.log(result)
  document.getElementById("iOut").innerHTML = result.length > 0 ? result[0].answer : defaultText;
)
<div>
  <p1 id="iOut">?</p1>
</div>
<form id="inputForm">
  <div>
    <input id="uIn" value="" />
  </div>
  <button>SUBMIT</button>
</form>

【讨论】:

我的代码还有另一个问题。我有一个代码在寻找 GOOD 并回复“那很好”。然后还有另一个代码在寻找 GOODBYE 来回复“Bye”,但它却在回复“That's good”。 发布完整的示例总是有帮助的。包含将查找字符串。现在你正在接受单词,我们将需要正则表达式 或者先测试最长的单词。我会更新 我知道我可以重新安排订单,但我希望有另一种方式。我有按字母顺序排列的代码,以便于编辑。看来我必须重新排列所有 280 行。 查看带有对象和正则表达式的更新版本【参考方案2】:

你会想要使用 .includes() 而不是 .contains()。

https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/String

我建议您熟悉 Chrome 的开发者工具。比如打开浏览器,输入"xyz".,你会看到各种可用的方法,contains()不在列表中。

另外,正如@mplungjan 指出的,这里还有其他问题。

"Hi" || "H" 计算结果为“嗨”。所以"HI"在这里完全被忽略了。

您可以改为写finalKey.contains("Hi") || finalKey.contains("H"))。当您添加测试时,这会变得很麻烦。

另一种方法是按照以下思路使用函数式编程:

const wordsToTest = ['FOO', 'BAR'];
if (wordsToTest.filter(word => finalKey.includes(word).length) 

【讨论】:

代码还有 4 个问题。看我的回答。【参考方案3】:

我意识到我在之前的回答中犯了一个根本性的错误,所以我想出了另一个解决方案。使用这种方法,您不必制作多个 if/else 语句,而是只需将新对象添加到数组中,我希望在查看时它是非常自我解释的 :)

<html>
<div>
  <p1 id="iOut">?</p1>
</div>
<div>
  <input id="uIn" value=""></input>
</div>
<button onclick="regis()">SUBMIT</button>

<script>


  function regis() 

    let key = document.getElementById("uIn").value;
    let finalKey = key.toUpperCase();
    let match = false;

    // Words to test for 
    autoComplete = [
         // Hey
            response: "hey",
            input: [
                'HI',
                'H',
            ]
        ,
         // Bye
            response: "Bye",
            input: [
                'BYE',
                'GOODBYE',
            ]
        
    ]

    for (potentialMatch of autoComplete)
        for (input of potentialMatch.input)
            if (input === finalKey)
                document.getElementById("iOut").innerHTML = potentialMatch.response;
                match = true;
            
        
    

    if (match === false)
        document.getElementById("iOut").innerHTML = "? Try again";
    
    
</script>

</html>

【讨论】:

如果您的目标是学习/练习 JavaScript,那么您就在路上。这可以。但一般来说,你必须编写的代码越少越好,你可以使你的代码数据驱动的越多越好。您的响应列表最终可能来自数据库等。因此您可以更简洁地将其写为: const inputToResponses = 'HI': 'hey, 'H': 'hey', 'BYE': 'Bye", ' GOODBYE': 'Bye'; document.getElementById("iOut").innerHTML = inputToResponses[finalKey.toUpperCase()] || 'Try again'; 最终你可能应该研究一下 React、Vue 等框架。 谢谢。我尝试了您的代码,但我需要它能够识别句子中的单词。如果我输入“他们说嗨”,它就无法识别“嗨”。

以上是关于我使用的是纯 JavaScript,但我继续收到以“不是函数”结尾的错误。如何做到这一点,以便我可以检测单词并做出相应的回复?的主要内容,如果未能解决你的问题,请参考以下文章

在用户滚动时继续修改 DOM

检测我的Mac应用程序是否崩溃,然后继续正常崩溃

Javascript在继续之前等待结果

停止并继续javascript函数[重复]

如何使 HTML5 画布适合动态父/弹性框容器

什么是纯 JavaScript 的“hasClass”函数?