Eloquent Javascript:未捕获的类型错误:无法读取属性'indexOf'的未定义
Eloquent Javascript: Uncaught TypeError: Cannot read property 'indexOf' of undefined
-
我正在学习基于Eloquent JavaScript的JavaScript,在其中一章中,我遇到了这个错误。不确定我在这里做错了什么。针对代码
return journal.events.indexOf(event) != -1
,我收到一个错误"无法读取未定义的属性'indexOf'" -
另外,有人能解释一下这条线是如何工作的吗?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
。
- TypeError:无法读取属性'推'未定义的JavaScript
- 同样,同样的错误'ahorcado.js:26未捕获类型错误:无法读取属性'beginPath'
- 未捕获的类型错误:无法读取属性'删除'的未定义
- AngularJS指令出错-无法读取属性'编译'的未定义
- 未捕获的类型错误:无法读取属性'name'即使它存在,也无法定义
- 看到“;未捕获的类型错误:无法读取属性'weight'未定义的“;尽管按照字面上的指示
- 无法读取属性'材料'未定义的Three.js
- 得到"TypeError:无法读取属性'filename'未定义的“;调用“npm start
- Soundcloud api"未捕获的类型错误:无法读取属性'uri'“未定义”;
- 未捕获的类型错误:无法读取属性'addEventListener'的null chrome扩展名
- Soundcloud Javascript SDK 3.0-回调无法读取属性'connectCallback
- 未捕获的类型错误:无法读取属性'状态'在react中为null
- JavaScript承诺-无法读取属性'那么'的未定义
- Javascript Float32数组抛出无法读取属性'0'即使数组定义良好,也为null
- 未捕获的类型错误:无法读取属性'中止'的未定义
- 角度推入数组给出:TypeError:无法读取属性'推'的未定义
- http/rxjs catch回调中的Angular 2重定向导致TypeError:无法读取属性'订阅'
- Javascript未捕获类型错误:无法读取属性'0'的未定义
- jQuery控制台错误:无法读取属性'top'的未定义
- TypeError:无法读取属性'findAll'的未定义