5

在任何 Web 浏览器中执行以下脚本将导致'wee'被发送到控制台。在 Node 中,它发送{}.

var d = 'wee';
console.log(this.d);

我意识到this在这种情况下,Node 指的是导出对象。我确实知道这个global变量,这不是我想要访问的。此外,上面的脚本也没有设置d在全局对象上。它到底去哪儿了?我可以在上面的脚本中显式访问它console.log(d);,但它似乎完全没有充分的理由隐藏在一些非标准空间中。

我也意识到删除对象上的varwill 声明,这是预期的行为,尽管在顶级范围内将其值存储在与“裸”变量不同的位置似乎很愚蠢。我的意思是,模块系统的重点不应该是某种预防全球污染的数字预防措施吗?在这里,打破模式似乎很容易,而做一些标准的事情却很难。dglobalvar

d也没有在module对象上声明。

我不必证明我为什么要问这个问题,但我会回答第一个巨魔,并附上“但是你为什么想做 taht hurr durrrr”。

var d = {};
d.bleep = 'y';
var a = Object.keys(d);

d.bloop = 'y';
d.blop = 'y';

var b = Object.keys(d);

// c = b - a;
var c = b.filter(function (item) {
    if(a.indexOf(item) === -1) {
        return true;
    }
    return false;
});

console.log(a,b,c);

就像我可以区分 的某些对象状态一样d,我应该能够区分顶级范围的状态。在浏览器中,这是window对象,this在顶级范围中被引用。我应该能够在脚本执行之前和之后评估环境的属性以确定很多事情,其中​​之一是检查在任意脚本的顶级范围内声明的函数和变量,然后将它们应用于导出对象。这将使以编程方式为未编写为模块的脚本生成模块包装器变得容易,并且简单forEach地应用于顶级函数和变量列表以分配whateverThisIs['varFunc']module.exports['varFunc']...

和东西...

这种行为似乎类似于匿名函数。在匿名函数this中可以引用window对象,var必须直接调用 s(因为它们在 anon func 的范围内),并且在没有var关键字的情况下声明的泄漏变量可能会在window对象处结束。我还没有阅读整个手册,也许这正是正在发生的事情,但是,我的印象是每个模块都在它自己的上下文(窗口)中执行,并且节点通过使用global和在模块上下文之间传递消息module.exports。 ..

我不知道。不过我想知道。如果你知道,请告诉我。

4

1 回答 1

12

因此,每个节点模块都被包装为函数的主体,如节点源代码中所示

NativeModule.wrapper = [
  '(function (exports, require, module, __filename, __dirname) { ',
  '\n});'
];

所以如果你用 声明一个变量var,它是模块的函数局部变量,基本上是那个模块的私有变量。它不是globalmodulemodule.exports或的属性this。如果您忘记了,它会作为属性var进入对象。global如果您在 上显式创建属性this,则该属性将进入exports其他模块并可用于其他模块。

这是一个小程序,希望能有所启发。

var aDeclaredVar = '*aDeclaredVar*';
undeclaredVar = '*undeclaredVar*';
this.aThisProperty = '*aThisProperty*';
module.aModuleProperty = '*aModuleProperty*';
module.exports.anExportProperty = '*anExportProperty*';

console.log('this', this);
console.log('this === exports', this === exports);
console.log('this === module', this === module);
console.log('this === module.exports', this === module.exports);
console.log('aDeclaredVar', aDeclaredVar);
console.log('undeclaredVar', undeclaredVar);
console.log('this.aThisProperty', this.aThisProperty);
console.log('module.aModuleProperty', module.aModuleProperty);
console.log('module.exports.anExportProperty', module.exports.anExportProperty);
console.log('global.undeclaredVar', global.undeclaredVar);
console.log('global.aDeclaredVar', global.aDeclaredVar);

它的输出:

this { aThisProperty: '*aThisProperty*',
  anExportProperty: '*anExportProperty*' }
this === exports true
this === module false
this === module.exports true
aDeclaredVar *aDeclaredVar*
undeclaredVar *undeclaredVar*
this.aThisProperty *aThisProperty*
module.aModuleProperty *aModuleProperty*
module.exports.anExportProperty *anExportProperty*
global.undeclaredVar *undeclaredVar*
global.aDeclaredVar undefined
于 2013-03-08T05:51:51.080 回答