vars在Nodejs中存储在哪里?

问题描述:

在任何Web浏览器中执行以下脚本将导致'wee'被发送到控制台。在节点中,它发送{}vars在Nodejs中存储在哪里?

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

我意识到,在节点this指的是在这种情况下的导出对象。我知道global变量,这不是我想要访问的。此外,上面的脚本也没有在全局对象上设置d。它到底在哪里?在上面的脚本中,我可以通过console.log(d);明确地访问它,但它似乎在一些非标准空间中隐藏起来,没有任何理由。

我也意识到,去掉varglobal对象,这是预期的行为虽然看起来愚蠢有var在顶层范围存储在不同的地方比“裸”变量及其值上宣布d。我的意思是,模块系统应该是防止全球污染的一种数字预防措施吗?在这里,打破模式似乎很容易,而且做一些标准工作很困难。

d也未在module对象上声明。

我不必证明为什么我会问这个问题,但我会回答第一个巨魔来与“但你为什么想要做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引用。我应该能够在脚本执行之前和之后评估环境的属性,以确定很多事情,其中​​之一是检查在任意脚本的顶部范围内声明的函数和变量,然后可以将它们应用于导出对象。这将可以很容易地编程生成其不与应用的顶层函数和变量列表中指定whateverThisIs['varFunc']module.exports['varFunc']简单forEach写成模块脚本模块封装...

和东西...

此行为看起来像一个匿名函数。在一个匿名函数中,this可能指的是window对象,var将不得不直接调用(因为它们在anon func的作用域中),没有var关键字的声明的泄漏变量可能会在window对象处结束。我还没有阅读整个手册,也许这正是发生了什么,但是,我的印象是,每个模块在自己的上下文(窗口)中执行,并且节点通过使用global在模块上下文之间传递消息,以及module.exports ...

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

+2

它将出现在局部变量的范围。在一个模块中,你的代码被封装在一个函数中。你只是看不到它。 – 2013-03-08 05:20:57

+0

那么它只是一个匿名函数呢?当然? – Kastor 2013-03-08 05:24:01

+2

是的......我不记得它是否是匿名的,但这并不重要。这是一个功能。为该函数定义的第一个参数是'exports',并且将一个空对象传递给该参数。同一个对象被设置为函数的this值。你可以用'console.log(arguments [0] === exports,arguments [0] === this);'来测试,并且你将会得到'true'。 – 2013-03-08 05:27:49

所以,如果你声明与var一个变量中的每个节点模块被包装成一个函数体为shown here in the node source code

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

因此,它在功能上本地的模块,基本上该模块私有变量。它不是globalmodulemodule.exportsthis的财产。如果您忘记了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 
+0

感谢您的源代码链接。 :D我从来没有试过反思一个函数的本地变量。我不知道是否有黑客做这件事,但肯定我现在看到的行为很有意义,因为我知道上下文。这就像书写小书签一样。 – Kastor 2013-03-08 06:08:33

+0

所以我试着运行一个脚本,将结束包装...};我要去找别的事情去做。 :D – Kastor 2013-03-08 06:27:05

+0

感谢您解决这个问题...正在编写一个本地节点扩展,并且在这一天挣扎了好几天! +1 – jkp 2013-05-24 17:54:12