简体   繁体   中英

Nodejs: Don't run `new class` with export

this is my config:

const one = new one()
const two = new two()

export default {
  one,
  two
}

And this is my classes:

export class one {
  constructor () {
    console.log("one");
  }
}

export class two {
  constructor () {
    console.log("two");
  }
}

And this is my setup:

import runner from "./";
runner.one

Why after call runner.one , also runner.two running?!

I want to run only runner.one

It happens in here:

const one = new one()
const two = new two()

cause You defined in constructor() methods of both classes to do console.log

when You call new ClassNameHere() it executes constructor()

You could simply export classes instead of instantiating them:

runners.mjs

export class one {
  constructor () {
    console.log("one");
  }
}

export class two {
  constructor () {
    console.log("two");
  }
}

executor.mjs

import * as runners from "./runners";

const one = new runner.one();

OR name classes CapitalizedCamelCased:

runners.mjs

export class RunnerOne {
  constructor () {
    console.log("one");
  }
}

export class RunnerTwo {
  constructor () {
    console.log("two");
  }
}

executor.mjs

import {RunnerOne} from "./runners";

const one = new RunnerOne();

It's happing because you're instantiating both of them globally using const specifier.

When you do this, the code calls the constructor of each class as soon as it comes across instantiation ( new keyword).

const one = new one()
const two = new two()

export default {
  one,
  two
}

If this is not what you want, and you want them to initialize separately, there could be multiple ways to achieve that.

One is to separately instantiate them, before you access them. (You could use it in a situation where you still need access to instantiated object inside the class you're instantiating them in). Something like this:

Class that contains one and two:

(assuming you define your classes in file onetwo.mjs )

import * as ot from "./onetwo.mjs";

let one;
let two;

function instantiateOne() {
  one = new ot.one();
}

function instantiateTwo() {
  two = new ot.two();
}

export default {
  one,
  two,
  instantiateOne,  // expose methods needed to create instances
  instantiateTwo,
}

Class that uses above:

import runner from "./";

runner.instantiateOne(); // this will only create instance of 'one'

runner.one; // accessing one

Of course there are other ways, and it might need more changes to make it work in your project, but this is one of the patterns. Just be aware when using such a strategy, you either always check before using the object ( one or two ) that they have been instantiated, or you ensure you do it at start.

NOTE: This is just to give you an idea. This isn't a concrete implementation. If you do want to implement something like this, you'll have to handle all edge cases (example, prevent re-initialization etc.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM