-1

There seems to be two different way to define a method within a class.

class Foo {
    handleClick = e => {
        // handle click
    }
    // and
    handleHover(e) {
        // handle hover
    }
}

My question is what is the difference between the two?

When transpiled, they give decidedly different results:

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Foo = function () {
    function Foo() {
        _classCallCheck(this, Foo);

        this.handleClick = function (e) {}
        // handle click

        // and
        ;
    }

    _createClass(Foo, [{
        key: "handleHover",
        value: function handleHover(e) {
            // handle hover
        }
    }]);

    return Foo;
}();

But I can't seem to discern what the differences are. Is it a binding issue?

Thanks!

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
abustamam
  • 1,597
  • 2
  • 13
  • 21
  • 1
    It's just the difference between an arrow function and a function expression. The method syntax is just syntactic sugar for function expressions. – Mike Cluck Oct 21 '16 at 20:53
  • I reopened the question since the duplicate doesn't really apply here. Note that your code is not valid ES6. It uses a feature proposal for a future version of ES. – Felix Kling Oct 21 '16 at 22:52

1 Answers1

3
class Foo {
    handleClick = e => {
        // handle click
    }
}

is not ES6. It's a proposal for a future version of ES.

The equivalent ES5 code to your example would be

class Foo {
    constructor() {
        this.handleClick = e => {
            // handle click
        }
    }
    // and
    handleHover(e) {
        // handle hover
    }
}

and the equivalent ES6 code to your example would be

function Foo() {
  this.handleClick = function(e) {
      // handle click
  }.bind(this);
}

Foo.prototype.handleHover = function(e) {
    // handle hover
}

So basically handleClick is autobound to the instance, which can be useful for event handlers, but it comes at the cost of creating a new function for every instance.

For more information see

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Oh interesting. I hadn't noticed that I had ticked `stage-2` in my Babel REPL. Unticking it threw a syntax error, which makes sense. So it essentially "autobinds" but creates a new function whenever the `new` is invoked. Makes sense now, thanks! – abustamam Oct 21 '16 at 23:10
  • 1
    Note that "autobinding" is a consequence of using an arrow function, not using a "class field". I.e. `handleClick = function(){}` would define the function inside the constructor, but you wouldn't get autobinding. – Felix Kling Oct 21 '16 at 23:24