开发者问题收集

不明白错误“Uncaught TypeError:”

2020-11-16
236

我试图在我的对象中打印出一个 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。

1个回答

问题在于您没有使用 let 定义 i 。这意味着您正在使用 全局 变量 i 。迭代后, i 将为 allTheToDos.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);
}

解决方案是使用 let 定义 i (不要使用 var ,否则您会遇到同样的问题)。使用 leti 的作用域限定在块内,因此每次 for 迭代都有自己的 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);
}
3limin4t0r
2020-11-16