Classes and arrow functions es2019

Doing a search to see where we are currently with classes and private methods and came across this sitepoint article https://www.sitepoint.com/javascript-private-class-fields/

It appears you can now define methods with arrow functions bound to this, which came as a bit of a surprise.

One difference is arrow methods are defined as if inside of a constructor and are created on the instance rather than the prototype

Just some tests

Arrow method

class Test1 {
  a = 10

  // created on the instance
  loggit = () => {
    console.log(this.a)
  }
}

const test1 = new Test1()

test1.loggit() // expect undefined get 10

console.dir(test1)
/*
Test1
  a: 10
  loggit: () => { console.log(this.a) }
  __proto__: Object
*/

Prototype method

class Test2 {
  a = 30

  // created on the prototype
  loggit() {
    console.log(this.a)
  }
}

const test2 = new Test2()
test2.loggit()  // expect 30 get 30

console.dir(test2)
/*
Test2
  a: 30
  __proto__:
    constructor: class Test2
    loggit: ƒ loggit()
    __proto__: Object
*/

Object Literal

Arrow function will still fail here

const testLiteral = {
  a : 20,
  loggit: () => {
    console.log(this.a) // this is found on window
  }
}

testLiteral.loggit() // expect undefined get undefined

Just thought I would share.

The rationale behind this syntax is a shorter form for binding methods manually (a pattern ubiquitous in React, for instance):

class MyComponent {
  constructor () {
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick (event) {
    // ...
  }
}

So we can then pass the method around without having to worry about the this context any more, such as e.g.:

class MyComponent {
  constructor (element) {
    this.element = element
    this.handleClick = this.handleClick.bind(this)
  }

  init () {
    this.element.addEventListener('click', this.handleClick)
  }

  destroy () {
    this.element.removeEventListener('click', this.handleClick)
  }

  handleClick (event) {
    // `this` always refers to the MyComponent instance now
  }
}

As you can imagine, all the manual this binding can get cumbersome rather quickly… I agree that the syntax is confusing when compared to object literals though, always kinda bugged me too. ^^

1 Like

Perfect example. Obviously without the binding set, ‘this’ would be the element rather than the MyComponent instance.

Thanks :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.