2

A class I am writing in NodeJS v8.10 (Webpack built) looks like its about to get really large. I want to break the methods out to their own files, but I also want to maintain the ES6 Class syntax since I come from an OOP background.

Is there a nicer ES6 syntax to implement methods of a class from other files?

I am presently extending the prototype per the code below, but it would be nice to have everything within the class braces "{}".

const fnClose = require('./close');
// about 20 more methods required in here

class Door {
  constructor() {}
  // close: require('./close'); // this would be nice!
}

/*
  it doesn't seem to matter if the exports line comes 
  BEFORE the prototype extensions; it still exports the
  'close' method with the Door class.
*/

// module.exports = Door; // works, just looks wrong here

Door.prototype.close = fnClose;
// about 20 more methods added to class here

module.exports = Door; // the natural place for exports

UPDATE

Based on the spark that Oliver provided in his answer below, this code can be refactored to bring the methods "inside the braces" like so. This isn't as "ES6" as I was hoping; a cleaner syntax would be nice. But this does get the job done!

const fnClose = require('./close');
// about 20 more methods required in here

class Door {
  constructor(...args) {
    // PROPERTIES
    this.species = 'Oak';
    // METHODS - FROM THEIR OWN FILES!
    this.close = fnClose; // how to close the door
    // CONSTRUCTOR CODE
    // <do stuff with args>
  }
}
module.exports = Door;

/*
  And thats it. everything tucked inside the 
  class, no need for prototype extenstions.
  Does not appear to be a need for Babel though.
*/
2
  • 4
    If you're finding you want to split your classes across multiple files, that might be an indication that the class is getting too big and the class itself should be split into smaller ones more focussed on what they provide Commented Nov 7, 2018 at 11:10
  • Thats a good observation, and should be considered. These methods all need to act on the "Door" properties though. The length of the Door.js file is the only concern; its getting unwieldy. I am giving the "code folding" ability of VSCode a real workout! Commented Nov 7, 2018 at 11:15

1 Answer 1

3

As James Thorpe indicates, it may be that your class itself is growing too large. That being said, if you're using babel, then you can class fields to achieve something that, at least as far as I can see, will achieve the same effect:

function test() {
  console.log('called test')
  console.log(this.value)
}

class TestClass {
  value = "This is the test value";
  runTest = test;
}

const x = new TestClass();

x.runTest()

Without babel, you cannot use class variables, as they aren't supported in js just yet. There is a proposal which is at stage 3 at the time of writing, and babel can transpile it for us.

The snippet above is using babel to get things to work. You ask in your comment whether babel is just converting this to the same code as you have. It's similar, but different in a few key ways. Babel transpiles it to this (using their sandbox):

"use strict";

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

function test() {
  console.log('called test');
  console.log(this.value);
}

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

  this.value = "This is the test value";
  this.runTest = test;
};

var x = new TestClass();

x.runTest();

So it isn't using the class syntax at all. It's useful to remember that class in javascript is just syntactic sugar in any case, so something similar to this is going on behind the scenes when you use class in any case.

Babel does seem to require a plugin for this, details can be found here.

Sign up to request clarification or add additional context in comments.

3 Comments

So I implemented this a little differently. In the constructor I used this.close = fnClose; and that gets it "within the class braces" like I was hoping for, sans cool ES6 of course. Question: what is Babel needed for in your answer?
I am not sure what is going on here. If I run your code in Node I get SyntaxError: Unexpected token =. But yet your code snippet works here. Is SO using Babel to transpile your example? If so that's pretty kewl LOL. Is Babel just doing what I did in my update, and moving those class lines into the constructor?
@GeekStocks I've updated the answer, and yes babel is indeed transpiling the code in the example ,you can turn it on with stack snippets

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.