Eloquent Javascript需要功能解释

Apa*_*ear 3 javascript module require

作者解释的最小实现需要的功能在这里,看起来像:

function require(name) {
  var code = new Function("exports", readFile(name));
  var exports = {};
  code(exports);
  return exports;
}

console.log(require("weekDay").name(1));
// ? Monday
Run Code Online (Sandbox Code Playgroud)

我很难理解到底发生了什么,主要是因为这个例子不完整.现在,我接受了readFile()以字符串格式返回的代码.这部分让我感到困惑:为什么var exports要传递给代码,它在做什么,为什么要返回?exports对象如何返回readFile已检索的代码?

Ama*_*dan 6

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
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为code它被构造为好像是这个函数:

function(exports) {
  var days = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
  ];
  function name(dayNo) {
    return days[dayNo];
  }
  exports.name = name;
}
Run Code Online (Sandbox Code Playgroud)

我们传入{}此函数,它将修改它

{
  name: function(dayNo) {
    return days[dayNo];
  }
}
Run Code Online (Sandbox Code Playgroud)

days封闭处捕获的位置,但外部世界不可见.这允许我们只访问模块中明确添加到exports(例如name)的内容,同时隐藏所有不是(比如days)的内容.