一个关于导出对象的问题
发布于 10 年前 作者 gaoguoxin 4088 次浏览 最后一次编辑是 8 年前

一个模块中的JS代码仅在模块第一次被使用时执行一次,并在执行过程中初始化模块的导出对象。之后,缓存起来的导出对象被重复利用。

如上所说,当我看到这句话的时候,知道缓存导出对象是为了提高运行效率,但是随后又想到了一个问题,就是,如果我第一次使用的时候,某个模块的导出对象被缓存了,那么当我修改了这个模块的导出对象后,这个模块应该不会再次被初始化了(因为被缓存了),但是问题是,我每次在修改了一个模块的导出对象后,这个导出对象都是最新的,所以我觉得,应该是有某种机制,发现了这个导出模块儿被修改了,然后重新初始化了一下,然后再次存入缓存了,不知到这么说对不对,还有,这中机制到底是什么机制?求指点~~

counter.js

var i = 0;

function count() {
    return ++i;
}

exports.count = count;

main.js

var counter1 = require('./util/counter');
var    counter2 = require('./util/counter');

console.log(counter1.count());
console.log(counter2.count());
console.log(counter2.count());

结果

1
2
3

难道上面的话是对require的解释? 也就是说,每次更改了代码后都要重新启动以加载所有文件,并在第一次require的时候进行导出模块的初始化?

5 回复

你这明显是逻辑思维的错误.

counter1 === counter2 === require.cache['...目录/util/counter']
counter1.count()
counter2.count()
counter2.count()
不一样,是因为i值已经被你给闭包缓存了

一楼的解释很好,闭包和模块缓存是两个问题。模块缓存是以路径作为key的,require()方法会将路径转为真实路径,并以真实路径作为索引,将编译执行后的结果存放在缓存中,以使二次加载时更快。在一个模块中定义的全局变量,会被所有的导出对象共享,所以修改会同时体现在其他的对象中。

谢谢回复,“在一个模块中定义的全局变量,会被所有的导出对象共享,所以修改会同时体现在其他的对象中” 这句话很重要,谢谢

二楼解释的很好。

回到顶部