9

This code below should work as expected, and log "meow", here an example.

function Cat () {
  this.animalNoise = 'meow' 
}

Cat.prototype.sound = () => {
  console.log(this.animalNoise)
}

let cat = new Cat()
cat.sound()

It doesn't work, this error appears TypeError: Cannot read property 'animalNoise' of undefined and when you convert the arrow function to an actual function declaration it works. It seems like with the arrow function, I no longer have access to this. What's going on here?

To be clear, the above code does not work where the following does, and I'm very curious why.

function Cat () {
  this.animalNoise = 'meow' 
}

Cat.prototype.sound = function() {
  console.log(this.animalNoise)
}

let cat = new Cat()
cat.sound()
Jeremy
  • 1
  • 85
  • 340
  • 366
ThomasReggi
  • 55,053
  • 85
  • 237
  • 424
  • An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and **lexically binds the this value** -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – elclanrs Dec 10 '15 at 17:32
  • 3
    There have been multiple questions about this already. Please use the search. – Felix Kling Dec 10 '15 at 17:34
  • In general though, I'm curious how/where people learn about arrow function *without* also learning about how `this` behaves in arrow functions. That difference is such an integral part of arrow functions that it seems impossible to me to not know about it. – Felix Kling Dec 10 '15 at 17:39

1 Answers1

12

Arrow functions perform lexical binding and uses the surrounding scope as the scope of this. For example, imagine (for some weird reason) you define Cat inside of a Dog constructor.

function Dog() {
  // do dog like things
  function Cat() { ... }
  Cat.prototype.sound = () => {
    // this == instance of Dog!
  };
}

So whatever the surrounding scope is becomes the scope of an arrow function.

Mike Cluck
  • 31,869
  • 13
  • 80
  • 91