如果我多次需要一个文件,它会被多次解析吗?

Will a file be parsed multiple times if i require it multiple times?

我有一个 .js 文件,其中包含 class 定义(使用 class 语法,而不是函数,以防万一)。然后我想要一个包含多个文件的文件夹,每个文件都是一个函数,它创建一个具有不同属性和 returns 的实例的 class 的不同实例。 当然,单实例创建文件无法访问 class 信息,除非这些文件中的每一个都有自己的 "require("class definition.js");"线。 关键是,由于我将有数百个所述实例创建文件,重复的 "require" 会影响我的性能吗?我不相信 JavaScript,我基本上害怕它会在每次 "require" 出现时解析并替换 class 定义。有谁知道是否会发生这种情况?如果有,有什么解决方法吗?谢谢


相关代码示例:

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

我想要的确实是类似于 c++ 的 .h 文件,类似于 class 定义文件的“#pragma once”指令。

javascript 中的模块和文件是单例,这意味着如果您需要一个文件 50 次,它们都将指向一个单一实例。以这段代码为例:

`// 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'));`

你可能认为你会console.log输出4个不同的随机数,但它实际上会输出同一个数字4次,因为每个require语句都会指向文件的一个实例a.js .

进一步阅读:https://willi.am/blog/2014/10/12/understanding-nodes-require-function/

tl;博士

不会。文件只会被访问、解析和执行一次。

nodeJS 中用于从其他 'modules' 导入代码的 require 函数使用缓存。每当第一次需要 module/file 时,它会从磁盘读取并 'executed'。文件中分配给 module.exports 的值从 require 函数调用返回并缓存在 require.cache 中。每当再次需要相同的 module/file 时,在进程中,将返回缓存的副本。

您提供的示例代码不会像您预期的那样工作。在 JS 文件中声明的 vars、functions 或 classes 中的 None 被添加到全局范围(在 nodeJS 中)。需要一个文件,也不会自动将在该文件中声明的符号添加到 'current' 范围(与 Python 不同)。在其他地方需要的文件中,您必须通过将其分配给 module.exportsexports 来显式导出一个或多个 'objects'。鉴于此,您的 class_definition.js 应该是这样的:

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

然后您需要像这样在各种实例文件中使用它:

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

请注意,为了在此文件中构建对象,您将使用您为本地变量指定的名称,其中存储了从 require("class_definition.js") 返回的 'value'。 myclass 符号本身从未添加到当前范围,只有 myclass 符号指向的对象(包括 class 在内的所有内容都是内部对象)被缓存并由 require 返回。当然,如果您想使用相同的名称,您可以将 const MyClassLocally = require("class_definition.js"); 替换为 const myclass = require("class_definition.js");