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

时间:2018-05-03 17:40:23

标签: javascript node.js require

我有一个.js文件,其中包含一个类定义(使用类语法,而不是函数一,以防万一)。然后我想拥有一个包含多个文件的文件夹,每个文件都是一个创建所述类的不同实例的函数,具有不同的属性,并返回实例。 当然,单实例创建文件不能访问类信息,除非这些文件中的每一个都有自己的" require(" class definition.js");"线。 关键是,因为我将有数百个所述实例创建文件,所以重复"要求"杀了我的表现?我不相信JavaScript,我基本上害怕它会解析并每次更换类定义"要求"出现。有谁知道这是否发生?如果确实有任何解决方法?感谢。

相关代码示例:

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文件,类似于&#34; #pragma once&#34;类定义文件的指令。

2 个答案:

答案 0 :(得分:2)

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/

答案 1 :(得分:1)

TL;博士

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

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

您提供的示例代码无法按预期工作。在JS文件中声明的var s,functionclass es都不会添加到全局范围(在nodeJS中)。需要一个文件,不会自动将该文件中声明的符号添加到“当前”范围(与Python不同)。在其他地方需要的文件中,您必须通过将其分配给module.exportsexports来明确导出一个或多个“对象”。鉴于此,您的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")返回的“值”。这样的myclass符号从未添加到当前范围,只有对象(包括类的所有内容都是内部对象)myclass符号指向的缓存并由require返回。当然,如果您想使用相同的名称,您可以随const MyClassLocally = require("class_definition.js");替换const myclass = require("class_definition.js");