首页 > 解决方案 > 不理解错误“未捕获的类型错误:”

问题描述

我试图在我的对象中打印出一个 true 值,但由于某种原因,我不断收到此错误消息。

Uncaught TypeError: Cannot set property 'toDoIsRemoved' of undefined  
  at removeTask (main.js:85)  
  at HTMLButtonElement.<anonymous> (main.js:56)

它说第 56 行有问题:

deleteButton.addEventListener('click', ()=>{removeTask(allTheToDos[i])});

这是整个功能:

function generateHtml (){
    // Creating an Ul for my items
    let section = document.getElementById('mySection');
    let myUl = document.createElement('ul');
    myUl.className = 'listContainer';
    section.appendChild(myUl);

    // Creating the loop for my premade todo objects
    for(i=0; i<allTheToDos.length; i++){
        // Create a div wrapper for my li
        let myListWrapperItemContainer = document.createElement('div');
        myListWrapperItemContainer.className = 'listItemsWrapper';
        // Creating Checked button
        let checkedIcon = document.createElement('label');
        checkedIcon.className = 'checkedIcon listItemsIcon';
        checkedIcon.innerHTML = '<i class="fas fa-check"></i>';
        //Creating li
        let myLi = document.createElement('li');
        myLi.classList = 'listItem lineTrough';
        myLi.id= 'listItem';
        // Creating delete button
        let deleteButton = document.createElement('button');
        deleteButton.id ='deleteButton';
        deleteButton.className = 'trashCan listItemsIcon';
        deleteButton.innerHTML = '<i class="fas fa-trash-alt"></i>';
        // OnClick
        deleteButton.addEventListener('click', ()=>{removeTask(allTheToDos[i])});

        // Adding everything to my html
        myListWrapperItemContainer.appendChild(checkedIcon);
        myListWrapperItemContainer.appendChild(myLi);
        myListWrapperItemContainer.appendChild(deleteButton);
        myLi.innerHTML = allTheToDos[i].toDoItem;
        myUl.appendChild(myListWrapperItemContainer);
    }
}

和:

function removeTask (done){
    done.toDoIsRemoved = true;
    console.log(allTheToDos);
}

我希望能够单击我的待办事项上的任何按钮,并能够将值从 false 更改为 true。

标签: javascriptarraysobject

解决方案


问题是您没有定义iusing let。这意味着您正在使用全局变量iiallTheToDos.length在迭代之后。当您稍后单击事件处理程序时,它将使用此索引,其值为undefined.

简而言之,这是一个问题:

const letters = ["a", "b", "c"];

// GLOBAL i
for (i = 0; i < letters.length; i++) {
  const button = document.createElement("button");
  button.append(letters[i]);
  button.setAttribute("type", "button");
  button.addEventListener("click", () => {
    // The line below is not called within the loop, but when
    // you click the button. This happens after the loop is
    // finished, which is when i no longer matches
    // i < letters.length
    console.log(i, letters[i]);
  });
  document.body.append(button);
}

解决方案是定义i使用let(不要使用var,否则你会遇到同样的问题)。使用let将作用i于块,因此每个 for-iteration 都有自己的i变量,只有在同一个块中更改它时才会更改。

const letters = ["a", "b", "c"];

// define i using let, scoping it to the for-block
for (let i = 0; i < letters.length; i++) {
  const button = document.createElement("button");
  button.append(letters[i]);
  button.setAttribute("type", "button");
  button.addEventListener("click", () => {
    console.log(i, letters[i]);
  });
  document.body.append(button);
}


推荐阅读