I want to write my position of figures on chess board (checkers) from Node List of tiles. I define a 2-dimensional array and fill it with 0. And I can freely change the value, if I use this._matrix[0][1] = 1;
right at the start of method. However, when it comes to changing it inside of a forEach array, I get this type of error.
how it is supposed to finally be
My code:
class Game{
_matrix = Array(8).fill().map(() => Array(8).fill(0));
_board = document.querySelectorAll("div.container>div"); // all tiles
constructor(blackTiles){
this.blackTiles = blackTiles;
}
fillMatrix(){
console.log(this._matrix[0][1]) // 0
this._matrix[0][1] = 1 // no errors
console.log(this._matrix[0][1]) // 1
this._board.forEach(function(element, i){
if(i < 8){
if(element.classList.contains("infest")){ //tiles, that have figures, have class "infest"
try{
let row = i / 8;
let col = i % 8;
this._matrix[parseInt(row)][parseInt(col)] = 1; //error
} catch(Error) { console.error(Error); }
}
i++;
}
});
return this._matrix;
}
}
Full error:
TypeError: Cannot read properties of undefined (reading '_matrix')
at script.js:41:30
at NodeList.forEach (<anonymous>)
at Game.fillMatrix (script.js:35:21)
at window.onload (script.js:102:22)
As you correctly found, the problem is on that specific line.
That is because inside a function, (defined with function(){}
), this
refers to the function itself, not the containing context.
You have three options at this point.
this
(old school :)):const _this = this;
list.forEach(function(){
_this.something;
})
list.forEach((function(){
this.something;
}).bind(this));
list.forEach(() => {
this.something;
});
_handleSomething = () => {
this.something;
}
list.forEach(this._handleSomething);
I'd go for option 3.
Option 4 is useful when your function is an event handler that you need to remove afterwards.