JavaScript - indexOf不是一个函数

3

我有这个事件...

   <textarea id="chat"> </textarea>
   <button type="button" onclick="play_song();">talk</button>

触发以下函数
   var input = function() {
           var chat = document.getElementById("chat").value.split(" ");
           return chat && console.log(chat);
        }

然后还有这个函数

   function setIntersection(a, b) {

      var result = [];

      for (var i = 0; i < a.length; i++) {
         if (b.indexOf(a[i]) !== -1 && result.indexOf(a[i]) === -1) {
            result.push(a[i]);
         }
      }
    return result;
   }

一个 原型函数:

   Song.prototype.lyricsIntersect = function(input) {


      var bestSong = null;
      var bestCount = -Infinity;

      for (var i in songs) {
        var currentCount = setIntersection(songs[i].lyrics, input).length;

    if (currentCount > bestCount) {
        bestSong = songs[i];
        bestCount = currentCount;
    }
}

return bestSong && bestSong.name;
}

代码到这里结束:
   function play_song() {

    var id = Song.prototype.lyricsIntersect(input);
    var element = document.getElementById(id);
    element.play();
}

但是console.log返回: Uncaught TypeError: b.indexOf is not a function

然而,如果我测试var input = ["one", "two"];,则我会在依赖于input的代码中完成交集。

我错过了什么?


b是什么?也许你设置错了。 - code
1
HTMLе’ҢinputеҮҪж•°дёҺй—®йўҳжңүд»Җд№Ҳе…ізі»пјҹзӣёеҸҚпјҢжӮЁеә”иҜҘеҸ‘еёғеҰӮдҪ•и°ғз”ЁsetIntersectionзҡ„еҶ…е®№гҖӮ - Oriol
1
请注意:return chat && console.log(chat); 返回的是未定义,因为 console.log 的返回值是未定义。 - RobG
你正在将input作为b参数传递。input是一个函数。 - RobG
4个回答

3

我错过了什么?

在这里,您将 input 声明为全局变量并分配一个函数:

var input = function() {
    var chat = document.getElementById("chat").value.split(" ");
    return chat && console.log(chat);
}

我更喜欢函数声明,但各有所好。

在这里,你将input作为参数传递给Song.prototype.lyricsIntersect

var id = Song.prototype.lyricsIntersect(input);

这将把它分配给自己的变量input

Song.prototype.lyricsIntersect = function(input) {

然后调用 setIntersection

    var currentCount = setIntersection(songs[i].lyrics, input).length;

然后在setIntersection中,将其分配给b参数:

function setIntersection(a, b) {

并像数组一样对待:
     if (b.indexOf(a[i]) !== -1 && result.indexOf(a[i]) === -1) {

@RobG,我想到使用"声明函数"可以将"input"设置为"全局变量",并在其他的"函数"中作为"参数"传递。如果我需要一个"数组"作为结果,你会如何使用"函数声明"来实现呢? - 8-Bit Borges
函数声明实际上也是函数名称的变量声明。唯一真正的区别在于它们在任何代码执行之前被处理,而对于带有赋值的变量声明,虽然声明发生在执行之前,但赋值只有在执行那行代码时才会发生。这里肯定有很多关于 function name() {}var name=function() {} 的问题。 - RobG
@RobG 我明白了,函数声明是在脚本解析时处理的,而不是在运行时处理的,是这样吗?因此,如果使用函数声明,在变量声明和赋值之后就不需要再添加这一行 input(); 了(在声明变量 input 后我需要这样做)? - 8-Bit Borges
@data_garden - 是的。由于函数声明在执行之前被处理,因此您可以在最底部声明函数并在最顶部调用它。但是赋值不是这样,它们必须在赋值之后调用。 - RobG
要使用函数声明,只需执行 function returnChat() { ... },然后 var input = returnChat()。这样做要好得多,因为:1)正如所说,函数将在页面加载时运行并具有值,并等待您的行调用它,而无需占用周期。2)没有全局声明。您只需创建函数并调用它。3)在 C# 中,通常必须知道传递的变量类型。您不希望将匿名函数分配给变量并不知道它,而是声明其类型。最好习惯于像这样做。 - vapcguy

2
var currentCount = setIntersection(songs[i].lyrics, input).length;

应该是

var currentCount = setIntersection(songs[i].lyrics, input()).length;

这也依赖于输入被以下方式进行校正。
var input = function() {
   var chat = document.getElementById("chat").value.split(" ");
   return chat;
}

我想这个比我的答案好。这会将你的b变成一个数组,因此不会出现类型错误的问题。 - kemicofa ghost
只要将输入更改为按预期返回数组,它就可以正常工作-请参见编辑后的答案。 - Jaromanda X
@Jaromanda X,我恐怕input仍然是未定义的。 - 8-Bit Borges
@JaromandaX 我忘记在函数表达式后运行 input();。现在它不再是 undefined 了,而且它可以工作了。 - 8-Bit Borges

1
为了使用Array对象的indexOf函数,您的b变量必须是一个array。请检查您的b类型。
这里是关于Array.prototype.indexOf()函数的文档
编辑:
根据您提供的信息,似乎您的b是对input的引用。您需要确保input是一个array。在您提供的情况下,input实际上是一个函数而不是array

1
Array.prototype.indexOf 的当前文档实际上在 ECMA-262 ed6 中。;-) - RobG
@RobG 已经注意到了。但是它还没有在所有浏览器中实现吗? - kemicofa ghost
@Grimbode 是的。console.log 返回给我一个 array - 8-Bit Borges
1
@Grimbode - 如果你所说的 "it" 是指 Array.prototype.indexOf,那么它是在 ES5 中引入的,因此应该在除了 IE8 之外的所有正在使用的浏览器中都存在。如果你指的是 ECMA-262 ed 6,我认为没有任何浏览器完全实现它,但大多数新浏览器都有它的大部分功能。我提到 ECMA-262 ed 6 是因为它已经成为标准超过一个月了。ES5 已经四年了。;-) - RobG

0

尝试尽可能简化示例,您的函数(如已注明)未使用预期的参数调用(可能是错误的逻辑)。至于indexOf方法:

typeof [].indexOf // "function"

typeof ''.indexOf // "function"

任何实现迭代协议的数据类型都应该支持indexOf


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接