Have you ever encountered this error in javascript before TypeError: Cannot read properties of undefined (reading 'forEach')
there are many a causes for this error, but today, we would look at one. Take a look at the code below.
// index.js
const printNumbers = {
phrase: "The current value is",
numbers: [1, 2, 3, 4],
loop: () => {
this.numbers.forEach((number) => {
console.log(this.phrase, number)
})
}
}
printNumbers.loop();
to run this code open terminal and run node index.js
. It will throw an error
TypeError: Cannot read properties of undefined (reading 'forEach')
Cause
To understand what caused the error, we need to understand scope and arrow functions in javascript.
In javascript, Scope refers to the current context of code, which determines the accessibility of variables to javascript. There are two types of scope, Global and Local scope.
please refer to my other tutorial to understand more about scope.
An Arrow function doesn't have its own this
value. It uses the this
value of the enclosing lexical scope. In the code above, the this
keyword in arrow function should refer to properties and methods (function) of the printNumbers
object. However, objects in javascript do not have a lexical scope, therefore an arrow function will look outside (beyond) the object for the value of this
, what is outside ? the global
scope (window object) which does not have the numbers
property. Therefore, the Javascript engine adds the numbers
property to the window
object and sets its value to undefined
.
To fix the issue, you should use traditional functions as the method (function) of the object.
here is the same code, modified
// index.js
const printNumbers = {
phrase: "The current value is",
numbers: [1, 2, 3, 4],
loop(){ // ==> changes made
this.numbers.forEach((number) => {
console.log(this.phrase, number)
})
}
}
printNumbers.loop();
answer
The traditional function re-binds this
keyword.
Thank You, Please follow me
Top comments (1)
Cause of many troubles is poor design solutions. There is nothing that mandates the
loop()
to be a method ofprintNumbers
object.Take it out, making it a pure function:
and don't ever think of
this
again.