1

I have a .js file which contains a class definition (with the class syntax, not the function one, in case it matters). Then i want to have a folder with multiple files, each of which will be a function that creates a different instance of said class, with different properties, and returns the instance. Of course, the single instance creating file cannot access class information unless each of these files has its own "require("class definition.js");" line. The point is, since i'm going to have hundreds of said instance creating files, will the repeated "require" kill my performance? I dont trust JavaScript, i'm basically scared it will parse and replace the class definition each time "require" appears. Does anyone know if that happens? If it does is there any workaround? Thanks.


Relevant code example:

class_definition.js

class myclass { constructor(a) { this.a = a; } } 

instantiate_0.js

require("class_definition.js"); module.exports = function() { return new myclass(0); } 

instantiate_1.js

require("class_definition.js"); module.exports = function() { return new myclass(1); } 

test.js

var arr = []; for(var i=0; i<2; i++) { arr[i] = require("instantiate_" + i)(); } 

What i'd like to have is indeed something like c++'s .h files, something working like the "#pragma once" directive for the class definition file.

1
  • 1
    require will see that you have already required it in your code, and should get the cached required version back (more in the node.js docs). After requiring, it will then be cached in require.cache Commented May 3, 2018 at 17:48

2 Answers 2

2

Modules and files in javascript are singletons which means if you require one file 50 times, they will all point to a singular instance. Take for example this code:

`// file a.js module.exports = Math.random()` `// file main.js console.log(require('./a')); console.log(require('./a')); console.log(require('./a')); console.log(require('./a'));` 

You may think that you will console.log out 4 different random numbers, but it will really log out the same number 4 times because each require statement will point the one instance of the file a.js.

Further reading: https://willi.am/blog/2014/10/12/understanding-nodes-require-function/

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

Comments

1

tl;dr

It won't. The file will be accessed, parsed, and executed only once.

The require function used in nodeJS for importing code from other 'modules' uses caching. Whenever a module/file is required the first time, its read from disk and 'executed'. The value assigned to module.exports within the file gets returned from the require function call as well as cached in require.cache. Whenever the same module/file is required again, within the process, the cached copy is returned instead.

The sample code you provided will not work as you'd expect. None of the vars, functions or classes declared in a JS file are added to global scope (in nodeJS). Requiring a file, doesn't automatically add symbols declared in that file to 'current' scope either (unlike Python). In a file that would be required else where, you must export one or more 'objects' explicitly by assigning it to module.exports or exports. In light of this, your class_definition.js should be something like this:

class myclass { constructor(a) { this.a = a; } } module.exports = myclass; 

Then you'd require and use it in your various instance files like this:

const MyClassLocally = require("class_definition.js"); module.exports = function() { return new MyClassLocally(1); }; 

Notice that for constructing the object in this file you'd use the name you gave to the local variable where returned 'value' from require("class_definition.js") was stored. myclass symbol as such was never added to current scope, only the object (everything including a class is an object internally) which myclass symbol pointed to got cached and returned by require. You're, of course, free to replace const MyClassLocally = require("class_definition.js"); with const myclass = require("class_definition.js"); if you want to use the same name.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.