Node 不会 运行 来自 Eloquent Javascript 的示例,v8 会。这是怎么回事?

Node won't run example from Eloquent Javascript, v8 will. What's the deal?

下面的函数是从 Ch 中逐字复制的。 Eloquent Javascript 中的 10 个,它与 v8 解释器完美运行。但是,它在未定义对象 weekDay 的 Node 中爆炸。它在本书提供的沙箱解释器中也运行良好。有人可以解释一下吗?

(function(exports) {
  var names = ["Sunday", "Monday", "Tuesday", "Wednesday",
               "Thursday", "Friday", "Saturday"];

  exports.name = function(number) {
    return names[number];
  };
  exports.number = function(name) {
    return names.indexOf(name);
  };
})(this.weekDay = {});

console.log(weekDay.name(weekDay.number("Saturday")));

这是因为 Node 模块中的 this 没有指向全局对象。它指向那个模块的exports。这意味着 weekDay 不能用作全局变量。

// ---------v
console.log(exports.weekDay.name(weekDay.number("Saturday")));

// ---------v
console.log(this.weekDay.name(weekDay.number("Saturday")));

为了更广泛(和简化)地了解节点模块的外观,它基本上是获取您的代码并将其放入 IIFE 中。

所以如果这是你的模块...

this.foo = "bar"
console.log(exports.foo); // "bar"

之所以有效,是因为它实际上是这样的...

var exports = {};    // Generated by Node
(function(exports) { // Generated by Node

    this.foo = "bar"
    console.log(exports.foo); // "bar"

}).call(exports, exports); // Generated by Node

其中额外的代码行由 Node.js 生成。您可以看到它创建了一个对象,它同时用作 IIFE 函数的 this 值和 exports 参数。

他们还向 IIFE 传递了更多内容,但这显示了基本思想。