【问题标题】:Uncaught TypeError: Cannot read property 'toLowerCase' of undefined (Todo list application )未捕获的类型错误:无法读取未定义的属性“toLowerCase”(待办事项列表应用程序)
【发布时间】:2020-11-13 03:33:05
【问题描述】:

所以我正在学习和练习 Javascript。下面的代码实际上可以在您编写过滤器待办事项时呈现待办事项列表。问题是我无法理解这个 Uncaught TypeError: Cannot read property 'toLowerCase' of undefined 当我使用 LowerCase 并包含方法时。

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)
})

【问题讨论】:

  • 你的 todos 数组没有带标题的 todo 对象,所以return todo.title.toLowerCase().includes(filters.searchtext.toLowerCase()) 导致错误

标签: javascript html web dom frontend


【解决方案1】:

您在 todo 对象上引用了一个名为 title 的属性:

todo.title.toLowerCase()

但他们没有这样的属性:

{
    activity: 'order',
    completed: true
}

也许你的意思是引用activity

todo.activity.toLowerCase()

还要注意,列表中的第一个 todo 根本没有属性:

{}

这也可能导致同样的错误。你至少可以给它一个空的活动:

{ activity: '' }

【讨论】:

    【解决方案2】:

    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-property(第一个有 no 属性)。因此,当您尝试运行todo.title.toLowerCase() 时,您正在运行undefined.toLowerCase(),这没有任何意义。

    要解决问题,您必须做出选择:

    1. 确保每个待办事项都有title-property
    2. 通过运行(todo.title || '').toLowerCase()title 属性设为可选,如果todo.titleundefinednull 或另一个falsy 值,则使其回退到''

    祝你好运!


    当天晚些时候编辑:我刚刚了解到,如果你想在可选属性上运行函数(比如我们的例子中的标题),你可以使用 optional chainingnullish coalescing operator

    const a = [{foo: 'bar'}, {}]
    
    a.map(obj => obj.foo?.toLowerCase() ?? '-') // ['bar', '-']
    

    【讨论】:

      猜你喜欢
      • 2014-07-06
      • 2016-03-25
      • 2018-05-16
      • 2021-10-13
      • 1970-01-01
      • 2020-11-17
      • 2017-06-26
      • 2013-07-23
      相关资源
      最近更新 更多