0

This code:

'use strict'
function Ob() {}

Ob.prototype.add = () => {
  this.inc()
}

Ob.prototype.inc = () => {
  console.log(' Inc called ');
}

module.exports = new Ob();

Is used by this code:

'use strict'
const ob = require('./ob')
ob.add();

When calling the ladder one, I get this error:

this.inc is not a function

When I change the first snippet to this:

'use strict'
function Ob() {}

Ob.prototype.add = function() {
  this.inc();
}

Ob.prototype.inc = function() {
  console.log(' Inc called ');
}

module.exports = new Ob();

Everything is fine and I get:

Inc called

Why does the first version throw?

Update: How would I make it work using arrow functions?

Alex
  • 161
  • 1
  • 10

2 Answers2

6

It doesn't work using arrow functions because they capture the this of the current scope. In your sample code

'use strict'

function Ob() {}

Ob.prototype.add = () => {
  this.inc()
}

Ob.prototype.inc = () => {
  console.log(' Inc called ');
}

module.exports = new Ob();

there is no this when this code runs (okay, there is one, but at least it's not the object instance that was created by the constructor). Essentially, this code is equivalent to:

'use strict'

const that = this;

function Ob() {}

Ob.prototype.add = function () {
  that.inc()
}

Ob.prototype.inc = function () {
  console.log(' Inc called ');
}

module.exports = new Ob();

and then it becomes apparent that actually there is no function for that.inc(). That's why it does not work.

How to fix this using arrow functions? Well, I'd say, don't use arrow functions here, because it makes absolutely no sense, and they are not just another way of writing "normal" functions, they are something slightly different.

How to fix this in general? Use the old-fashioned function keyword, and everything will work as expected :-)

Golo Roden
  • 140,679
  • 96
  • 298
  • 425
0

Arrow functions don't introduce a new context. What that means is within an arrow function this will be the context from the function that it's contained within.

In the following example, the IIFE creates a context of window

(function () {
  function Ob() {}

  Ob.prototype.test = () => {
    console.log(this === window);
  };

  o = new Ob();
  o.test(); // true
}());

If you want to use a function with its own context, you'll have to use the full function keyword.

(function () {
  function Ob() {}

  Ob.prototype.test = function () {
    console.log(this === window);
  };

  o = new Ob();
  o.test(); // false
}());
zzzzBov
  • 174,988
  • 54
  • 320
  • 367