Eloquent Javascript 需要功能说明
Eloquent Javascript require function explanation needed
作者解释了 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()
returns 字符串格式的代码。真正让我困惑的部分是:为什么要将 var exports
传递到代码中,它在做什么,为什么要返回它? 如何 exports
返回 readFile
检索到的代码的对象?
此示例需要了解函数构造函数。
这可能有帮助:
$ node
> f = new Function("x", "return x + 2");
[Function]
> f(8)
10
在您的示例中,函数的主体是文件中的代码,您将在其中看到对变量 exports
属性的赋值。那么什么是exports
呢?它是一个最初为空的对象。模块的主体在调用时将 "fill it in"。在调用 code(exports)
之后,您将得到一个填充的对象,里面有很多好东西,它从 require
.
返回
示例:
假设文件包含
var x = 3
exports.y = 10 * x
然后你的调用将传入一个空对象,但执行函数会将 y
属性 添加到对象中,你将返回
{y: 30}
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
)。
作者解释了 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()
returns 字符串格式的代码。真正让我困惑的部分是:为什么要将 var exports
传递到代码中,它在做什么,为什么要返回它? 如何 exports
返回 readFile
检索到的代码的对象?
此示例需要了解函数构造函数。
这可能有帮助:
$ node
> f = new Function("x", "return x + 2");
[Function]
> f(8)
10
在您的示例中,函数的主体是文件中的代码,您将在其中看到对变量 exports
属性的赋值。那么什么是exports
呢?它是一个最初为空的对象。模块的主体在调用时将 "fill it in"。在调用 code(exports)
之后,您将得到一个填充的对象,里面有很多好东西,它从 require
.
示例:
假设文件包含
var x = 3
exports.y = 10 * x
然后你的调用将传入一个空对象,但执行函数会将 y
属性 添加到对象中,你将返回
{y: 30}
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
)。