Eloquent Javascript:未捕获的类型错误:无法读取属性'indexOf'的未定义

Eloquent Javascript: Uncaught TypeError: Cannot read property 'indexOf' of undefined

本文关键字:读取 属性 未定义 indexOf 错误 Javascript Eloquent 类型      更新时间:2023-09-26
  1. 我正在学习基于Eloquent JavaScript的JavaScript,在其中一章中,我遇到了这个错误。不确定我在这里做错了什么。针对代码return journal.events.indexOf(event) != -1 ,我收到一个错误"无法读取未定义的属性'indexOf'"

  2. 另外,有人能解释一下这条线是如何工作的吗?IndexOf不是应该返回指定值(在本例中为事件)出现的第一个位置吗?但我在书中看到,return journal.events.indexOf(event) != -1;行要么返回true,要么返回false。

    var journal = [];
    function addEntry(events, didITurnIntoASquirrel) {
        journal.push({
            events: events,
            squirrel: didITurnIntoASquirrel
        });
    }
    addEntry(["work", "touched tree", "pizza", "running",
              "television"], false);
    addEntry(["work", "ice cream", "cauliflower", "lasagna",
              "touched tree", "brushed teeth"], false);
    addEntry(["weekend", "cycling", "break", "peanuts",
              "beer"], true); 
    function hasEvent(event, entry) {
        return entry.events.indexOf(event) != -1;
    }
    console.log(hasEvent("pizza", journal));
    

在您的示例代码中,journal是一个数组

  var journal = []; <--- Array

因此,应使用索引访问events,如

journal[0].events.indexOf(event)
        ^
        |
        |

在这里,您需要找到正确的索引来获得您的事件

我不确定你在学习javascript方面有多远,所以如果其中一些听起来居高临下或显而易见,请原谅我。

让我们一步一步地把它分解。您从一个空数组开始。

var journal = [];
console.log(journal); //[]  
//it's defined. It's an empty Array.

通过对数组调用push,可以在数组的末尾添加一些内容。更多关于Array.push.

我不喜欢初学者使用这个例子,因为它希望您在将对象作为参数传递时已经知道可以定义它。这样做是因为您不需要对只使用过一次的对象进行变量引用,因此这是减少代码膨胀的好方法。但是,在教别人的时候,冗长要好得多,imho。

//Wait, what am I pushing into the journal array?
journal.push({
   events: events,
   squirrel: didITurnIntoASquirrel
});

这应该更有意义:首先创建一个对象。然后将该对象添加到"journal"数组中。函数addEntry(事件,didITurnIntoASquirrel){var temporaryObject={事件:事件,松鼠:didITurnIntoASquirrel};journal.prush(temporaryObject);}

现在,journal是一个数组,其第一个索引处有一个未命名的对象。

   1. console.log(journal); // [temporaryObject]
   2. console.log(journal[0]); - //temporaryObject

视觉上的差异是缺少parens,但这种差异很重要。在第1行有数组本身,在第2行有数组内部的内容(即对象)。在访问该对象的属性(如"events"或"松鼠")之前,您需要获取该对象(通过第2行的技术)。继续前进。

addEntry(["work", "touched tree", "pizza", "running", "television"], false);

接下来,我们调用addEntry函数。这里也有同样的困惑。我稍微改写了一下,使论点更容易理解。

var entry = ["work", "touched tree", "pizza", "running", "television"];
addEntry(entry, false);
//repeat 2 more times with different data

因此,我们首先定义一个数组,然后将其传递给addEntry函数。当addEntry函数运行时(当我们调用它时它将立即运行),"entry"参数将被表示为"events"参数(简单的方式:events=entry和didITurnIntoASquirrel=false)。关于参数与自变量的一些注记。

因此,您现在应该能够理解您正在向addEntry函数传递一个数组和一个布尔值。该函数基于那些通过参数引用它们的值来创建对象。然后将该对象添加到日志数组中。

你最终得到的是4个层次的深度。您有一个名为journal的数组,其中包含对象。这些对象有一个称为events的属性,这是一个不同的数组。该数组中有几个字符串。要访问事件数组并使用indexOf查看其中是否有给定的字符串,您需要一次遍历一个级别的深度。

//journal is the array, journal[0] is the object, journal[0].events is the property of that object
console.log(journal[0].events) //["work", "touched tree", "pizza", "running", "television"].

请注意,这与我们最初放入入口变量中的数据相同。这可能看起来不必要地复杂,但相信我,当你需要在面向对象编程中管理数据层次结构或"事物"之间的其他逻辑关系时,这种类型的结构在现实生活中很有用。

现在,到目前为止,我们所做的所有工作都是添加到日志数组中。我们现在想要一个函数来看看里面有什么。为什么是函数?因此,您不必一遍又一遍地重写相同的代码。

function hasEvent(event, journal) {
    return journal.events.indexOf(event) != -1;
}

到现在为止,我希望你能发现这个函数中的错误。journal.events不起作用,因为journal是一个数组,而不是一个对象(你跳过了一个级别,你的计算机不够聪明,不知道你的意思)journal[0]。events会起作用,这是因为你在告诉javascript("从journal数组中,我希望对象位于第一个槽中,并且该对象的events属性")。

最简单的修复方法是将日志[0]发送到hasEvent函数,而不是日志。注意,这只会检查日记账的第一个索引。实际上,您希望在hasEvent函数内部有一个for循环,或者包装对该函数的调用以检查所有索引。现在我们将对它们进行硬编码,因为我们知道有3个,但在现实生活中这不是一个好主意,因为以后期刊上可能会有3个以上的条目)。

此函数返回用-1调用indexOf()(某个数字或-1)的结果。让我们再次重写它,使它更有意义。

新增hasEvent功能:

//I renamed the variable so it makes more sense what it really is. It's the object, not the journal array.
function hasEvent(event, journalEntry) {
    var index = journalEntry.events.indexOf(event);
    var result = (index != -1); //true if it was found, false if it wasn't found.
    return result; //a boolean based on the above comparison.
}
//Ack! My kingdom for a "for loop". Don't worry about that right now.
console.log(hasEvent("pizza", journal[0]));
console.log(hasEvent("pizza", journal[1]));
console.log(hasEvent("pizza", journal[2]));

TL;DR以下是工作代码:http://jsfiddle.net/o8dg1ts6/1/

回答您的第二个问题:

"IndexOf不是应该返回指定值出现的第一个位置吗"

是,如果值是而不是在数组中找到,则indexOf返回-1。

因此,如果发现事件,则表达式indexOf(event) != -1将计算为true