2

If I'm importing a class into some other script, how can I pass parameters to that class constructor in ES6 syntax?

I would like to do something like this. I've seen various suggestions like wrapping functions or using factory pattern, but is there a cleaner simpler way of doing this?

// This is sudo code
import SomeClass from './SomeClassPath';
var thing = SomeClass(params);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
David Choi
  • 6,131
  • 10
  • 28
  • 28
  • Not sure what you're trying to do. It's always `new SomeClass(params)` (and it is a single param, btw). Please, explain what you're trying to do exactly. – Estus Flask Apr 21 '17 at 20:17
  • Hmm I thought using import for some class provides a singleton instance of that class no matter how many times import is called. Is this not true? – David Choi Apr 21 '17 at 20:46
  • 1
    This applies to any thing you're importing. Class instances won't be made singletons automatically. It just executes imported file once, that's how 'singleton' thing happens. Unless you're using it to export a singleton like `export const someClassInstance = new SomeClass`, it is not a concern. – Estus Flask Apr 21 '17 at 20:50
  • I think you mean pseudo-code. Or was that a play on words? :-) – stone Dec 05 '17 at 22:47

2 Answers2

17

I see that there is some confusion in your question, so let me clarify.

In ES6, you may know that you have two strategies when you need to export a module. You can use a default export or multiple exports. Let's take a very basic example (a simple logger around console):

function info(msg) {
  console.info(`[Info] ${msg}`);
}

function error(msg) {
  console.error(`[Error] ${msg)`);
}

Default export

Here we must group our functions. The most idiomatic way of doing this in JavaScript is with an object literal (see Revealing Module Pattern):

export default {
  info(msg) {
    console.info(`[Info] ${msg}`);
  },
  error(msg) {
    console.error(`[Error] ${msg}`);
  }
};

Then, in our client code, we will use this module like so:

import logger from './logger'

logger.info('Hello!');
logger.error('Oops!');

Multiple exports

Here we can export our functions independently:

export function info(msg) {
  console.info(`[Info] ${msg}`);
}

export function error(msg) {
  console.error(`[Error] ${msg}`);
}

Then, in our client code, we will use this module like so:

import {info, error} from './logger'

info('Hello!');
error('Oops!');

Done.

I suggest you to understand how the ES6 module system works with our functional example. It is exactly the same thing with classes...


Singleton?

By reading the comments, I have seen another confusion that requires clarification: the Singleton.

Singleton is a design pattern that makes it possible to instantiate a class just once. Now imagine that our class is the following:

export default class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
};

We could use it like this:

import Person from './Person';

let me = new Person('Baptiste', 'Vannesson'),
    you = new Person('David', 'Choi');

console.log(Object.is(me, you)); // false, so there are two instances of Person
console.log(me.firstName, me.lastName);  // Baptiste Vannesson
console.log(you.firstName, you.lastName); // David Choi

As you can see, Person has nothing to do with Singleton! It would be a Singleton with the following Java-inspired implementation:

export default (() => {

  class Person {
    // Private constructor
    constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }
  }

  return {
    // Public static factory method
    getInstance(firstName, lastName) {
      if (!Person.instance) {
        Person.instance = new Person(firstName, lastName);
      }
      return Person.instance;
    }
  };

})();

Client code:

import Person from './Person';

let me = Person.getInstance('Baptiste', 'Vannesson'),
    you = Person.getInstance('David', 'Choi');

console.log(Object.is(me, you)); // true, so there is only one instance
console.log(me.firstName, me.lastName); // Baptiste Vannesson
console.log(you.firstName, you.lastName); // Baptiste Vannesson (still me!)

For the sake of simplicity, you may prefer to export an instance directly:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
};

export default new Person('David', 'Choi');

Client code:

import person from './person';

// Person is not a constructor but a simple instance
let me = person,
    you = person;

console.log(Object.is(me, you)); // true
console.log(me.firstName, me.lastName); // David Choi
console.log(you.firstName, you.lastName); // David Choi

If you do that, this would be even simpler to use an object literal:

export default {
  firstName: 'David',
  lastName: 'Choi'
};

The client code does not change here.

Badacadabra
  • 8,043
  • 7
  • 28
  • 49
2

Passing parameter to your es6 module is very simple and straight forward. Just do this simple thing.

// This is sudo code
require('./SomeClassPath.js')(param);

Then inside the module file SomeClassPath.js do this

module.exports = function(param) {
 ....     
}
Emeka Obianom
  • 1,736
  • 3
  • 17
  • 36