How to get a reference to a class function in ES6?

Traveling Tech Guy picture Traveling Tech Guy · Aug 1, 2015 · Viewed 10.7k times · Source

Sorry if question is too simple, but I'm missing something here. Just switched an ES5 module that looked like:

module.exports = {
  func1: function(a, b) {...},
  func2: function(a, b) {...}
};

To an ES6 class that looks like this:

export default class {
  func1(a, b) {...}
  func2(a, b) {...}
}

And all was well: in both cases I could export mod from 'module'; and call mod.func1(a, b) and mod.func2(a, b).

However, I have a function that recieves a module function to call:

var caller = function(func, val1, val2) {
  let a = something(val1);
  let b = something(val2);
  return func(a, b);
};

When I call caller(mod.func1, x, y) I get the desired result with the first implementation, but an undefined is not a function with the second.

Printing out the value of mod.func1 returns [Function] in both cases, but clearly something else is returned from an ES6 class.

What am I doing wrong, and how can I get a class function I can call in another function?

Update: with the second implementation, I forgot to add the instantiation code:

import Mod from 'module';
var mod = new Mod();

Answer

Sean Vieira picture Sean Vieira · Aug 1, 2015
class MyClass {
  method(args) {}
}

is short hand for:

function MyClass() {}
MyClass.prototype.method = function(args){};

What you are looking for is a static method on the constructor, which in ES{3,5} is done this way:

function MyClass() {}
MyClass.method = function(args){};

and in ES6 is done with the static modifier:

export default class {
  static func1(a, b) { /* stuff */ }
  static func2(a, b) { /* stuff */ }
}

However, you can use short-hand methods even in an object, so using a normal object is clearer in the general case:

export default {
  func1(a, b) {/* stuff */},
  func2(a, b) {/* stuff */}
}

Why aren't prototype methods available on the constructor?

Because it's not that way in ES3 or ES5:

function MyClass() {};
MyClass.prototype.method = function(args) {};

MyClass.method  // undefined

var instance = new MyClass();
instance.method  // function(args) {}

Creating an instance is necessary to have access to methods on the prototype.