所以我正在学习和练习Javascript。下面的代码实际上有效,当您在过滤器Todos中编写代码时,它将呈现TODO列表。问题是我无法理解此Uncaught TypeError:当我使用LowerCase并包含方法时,无法读取未定义的属性“ toLowerCase”。
HTML文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Todos</h1>
<input type="text" placeholder="Enter something to do" id="new-todo-text">
<button id='add-todo'>Add Todo</button>
<input type="text" id="search-text" placeholder ='Filter todos'>
<div id='todos'></div>
<script src ='todo-experiment.js'></script>
</body>
</html>
JavaScript文件
const todos = [{},{
activity: 'order',
completed: true
},{
activity: 'clean',
completed: false
}, {
activity: 'Buy',
completed: true
}, {
activity: 'Do',
completed: false
}, {
activity: 'Excercise',
completed: true
}]
const filters = {
searchtext: ''
}
const renderTodos = function(todos, filters){
const filteredTodos = todos.filter(function (todo){
return todo.title.toLowerCase().includes(filters.searchtext.toLowerCase())
})
const incompleteTodos = todos.filter(function(todo){
return !todo.completed
})
document.querySelector('#todo').innerHTML = ''
const p = document.querySelector('h2')
summary.textContent = `You have ${incompleteTodos.length} todos left`
document.querySelector('body').appendChild(p)
todos.forEach(function (todo){
const p =document.createElement('p')
p.textContent = todo.text
document.querySelector('body').appendChild(p)
})
}
renderTodos(todos, filters)
document.querySelector('#add-todo').addEventListener('click', function(e){
console.log('Add a new todo ...')
})
document.querySelector('#add-todo').addEventListener('input', function(e){
console.log(e.target.value)
})
document.querySelector('#search-text').addEventListener('input', function(e){
filters.searchtext = e.target.value
renderTodos(todos, filters)
})
答案 0 :(得分:1)
您要在title
对象上引用名为todo
的属性:
todo.title.toLowerCase()
但是它们没有这样的属性:
{
activity: 'order',
completed: true
}
也许您打算引用activity
:
todo.activity.toLowerCase()
请注意,列表中的第一个todo
完全没有属性:
{}
这也可能导致相同的错误。您至少可以给它一个空的活动:
{ activity: '' }
答案 1 :(得分:1)
Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
几乎总是意味着未设置对象的属性,这也意味着现在也是如此。
您正在待办事项列表上运行todo.title.toLowerCase()
,
const todos = [{},{
activity: 'order',
completed: true
},{
activity: 'clean',
completed: false
},
// and some more
]
在此列表中,没有一个待办事项具有title
属性(第一个具有 no 属性)。因此,当您尝试运行todo.title.toLowerCase()
时,您正在运行undefined.toLowerCase()
,这没有任何意义。
要解决此问题,您必须选择:
title
属性title
使(todo.title || '').toLowerCase()
属性成为可选属性,如果''
为todo.title
,undefined
,则会使其退回到null
或另一个falsy值。当天晚些时候编辑:我刚刚了解到,如果要对可选属性(例如本例中的标题)运行函数,则可以使用optional chaining和nullish coalescing operator:
const a = [{foo: 'bar'}, {}]
a.map(obj => obj.foo?.toLowerCase() ?? '-') // ['bar', '-']