简体   繁体   中英

Should I avoid using top-level variables in module?

I'm writing code with React, and I'm trying to move some logics to modules, but I'm confused.

I have been writing modules like following lines.

// fooModule.js
let count = 0

export function countUp() {
    count += 1
}

export function getCount() {
    return count
}

This count variable can't be access from outer module as expected.

However, I noticed this variable status is keeping, When I twice importing this module, the variable status has shared in both.

So, Should I change to following?

// fooModule.js
export function countUp(count) {
    return count + 1
}

// someClass.js
import { countUp } from './fooModule.js'

const count = 0
const newCount = countUp(count)

Thanks.

Add: Thank you for many replies in a short time! I fixed wrong sample code.

Your second code won't work, because count is not in scope in fooModule , because you created it in someClass . If you want each importer of fooModule to have a separate binding for count , one option would be to export a function that, when called, creates a count variable, and returns a function that increments it and returns the new count:

// fooModule.js
export function makeCount() {
  let count = 0;
  return () => {
    count++;
    return count;
  };
}

// someClass.js
import { makeCount } from './fooModule.js';
const counter = makeCount();
console.log(counter()); // 1
console.log(counter()); // 2

Or, with generators:

// fooModule.js
function* makeCount() {
  let count = 0;
  while (true) {
    count++;
    yield count;
  }
}

// someClass.js
const counter = makeCount();
console.log(counter.next().value); // 1
console.log(counter.next().value); // 2

(you could also use return ++count instead of count++; return count; in both codes above, but that's a bit harder to read IMO)

require imports the target script once. Subsequent calls to require for that script will return the result of the first require call for that script. This is why it is OK to use circular dependencies, otherwise a circular dependency would result in an infinite loop.

What this means is that if you want separate instances, you should make a thing that makes those instances, then export that thing. Some of the things that make instances of things are:

  • Classes,
  • Constructors,
  • Factory functions, etc
// fooModule.js
export class Counter {
  constructor(count = 0) {
    this.count = count
  }
  countUp() {
    return ++this.count
  }
}

// index.js
const counterA = new Counter(1)
console.log(counterA.countUp()) // 2

const counterB = new Counter(0)
console.log(counterB.countUp()) // 1

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