David Choi
David Choi

Reputation: 6619

How do I pass constructor parameters to imported class in ECMAScript 6?

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);

Upvotes: 2

Views: 17538

Answers (2)

Emeka Obianom
Emeka Obianom

Reputation: 1794

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) {
 ....     
}

Upvotes: 1

Badacadabra
Badacadabra

Reputation: 8497

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.

Upvotes: 19

Related Questions