作者解释了 require 函数的最小实现 here看起来像:
function require(name) {
var code = new Function("exports", readFile(name));
var exports = {};
code(exports);
return exports;
}
console.log(require("weekDay").name(1));
// → Monday
我很难理解到底发生了什么,主要是因为示例不完整。现在,我已经接受 readFile()
以字符串格式返回代码。真正让我感到困惑的部分:为什么 var exports
被传递到代码中,它在做什么,为什么要返回它? 如何导出
对象返回 readFile
检索到的代码?
最佳答案
new Function("exports", body)
将创建一个匿名函数,它接受一个参数 ( exports
) 并执行在 body
中找到的代码.
exports
将被传递到函数体中的对象开始时是一个空对象,目的是模块体将用它想要暴露给世界其他地方的东西来填充它。然后执行函数(我们传入 exports
对象)。最后返回模块导出的东西。
这是一个更完整的例子:
fakeFileSystem = {
"weekDay.js": " \
var days = [ \
'Sunday', \
'Monday', \
'Tuesday', \
'Wednesday', \
'Thursday', \
'Friday', \
'Saturday' \
]; \
function name(dayNo) { \
return days[dayNo]; \
} \
exports.name = name; \
"
};
function require(name) {
var code = new Function("exports", fakeFileSystem[name + ".js"]);
var exports = {};
code(exports);
return exports;
}
console.log(require("weekDay").name(1));
// → Monday
这是有效的,因为 code
构造就好像它是这个函数:
function(exports) {
var days = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
function name(dayNo) {
return days[dayNo];
}
exports.name = name;
}
我们通过{}
进入这个函数,它将修改为
{
name: function(dayNo) {
return days[dayNo];
}
}
哪里days
被捕获在闭包中,但对外界不可见。这允许我们只访问模块中显式添加到 exports
的内容。 (如 name
),同时隐藏所有不是的东西(如 days
)。
关于javascript - Eloquent Javascript 需要函数解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29619451/