问题描述
在任何网页浏览器中执行以下脚本都会导致'wee'被发送到控制台。在Node中,它发送 {} 。
var d ='wee';
console.log(this.d);
我知道在Node 中这个指这种情况下的导出对象。我知道全局变量,这不是我想要访问的内容。另外,上面的脚本也没有在全局对象上设置 d 。它到底在哪里?我可以在上面的脚本中通过 console.log(d); 明确地访问它,但它似乎被隐藏在一些非标准空间中,没有任何理由。
我也意识到,删除 var 会声明 d on 全局对象,这是预期的行为,尽管在顶级作用域 c> var 存储其值时似乎很愚蠢在与裸体变量不同的地方。我的意思是,模块系统应该是防止全球污染的一种数字预防措施吗?这里看起来很容易打破模式,很难做一些标准的事情。
d 没有声明模块对象。
我不必证明为什么我问这个问题,我会回答第一个巨魔与一个但为什么你想要做的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;
}
返回false;
});
console.log(a,b,c);
以同样的方式可以区分 d ,我应该能够区分顶级范围的状态。在浏览器中,这是窗口对象,由顶级作用域中的 this 引用。我应该能够在脚本执行之前和之后评估环境的属性,以确定很多事情,其中之一是检查在任意脚本的顶部范围内声明的函数和变量,然后可以将它们应用于导出对象。这样就可以很容易地编写程序为脚本生成模块包装器,这些脚本不会被编写为具有简单的 forEach 的模块,而是应用于顶层函数和变量列表以分配 whateverThisIs ['varFunc'] to module.exports ['varFunc'] ...
和其他东西......
这种行为看起来像一个匿名函数。在一个匿名函数中,这个可以引用窗口对象, var s将不得不直接调用(因为它们在anon func的作用域中),而且在没有 var 关键字的情况下声明的泄漏变量可能会以 window 对象。我还没有阅读整个手册,也许这正是发生了什么,但我的印象是,每个模块在它自己的上下文(窗口)中执行,并且Node通过<$ $在模块上下文之间传递消息c $ c> global 和 module.exports ...
不知道。但我想知道。如果你知道,请告诉我。因此,每个节点模块都被封装为一个函数的主体,如 / joyent/node/blob/7d654be627f187f10c8df6b2a1020f88860202be/src/node.js#L800rel =noreferrer>
NativeModule.wrapper = [
'(function(exports,require,module,__filename,__dirname){',
'\\\
});'
]。
所以如果你用 var ,它对模块是本地函数,基本上是该模块的私有变量。它不是全球,模块, module.exports 或这个。如果您忘记 var ,它将作为属性进入全局对象。如果你明确地在这个上创建了一个属性,这个属性进入 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
DeclaredVar * aDeclaredVar *
undeclaredVar * undeclaredVar *
this.aThisProperty * aThisProperty *
module.aModuleProperty * aModuleProperty *
module.exports.anExportProperty * anExportProperty *
global.undeclaredVar * undeclaredVar *
global.aDeclaredVar undefined
In any web browser executing the following script will result in 'wee' being sent to the console. In Node it sends {}.
var d = 'wee'; console.log(this.d);
I realize that in Node this refers to the exports object in this case. I do know about the global variable, and that isn't what I'm trying to access. Besides, the script above does not set d on the global object either. Where the hell does it go? I can access it explicitly by console.log(d); in the script above but it appears to be stashed away in some nonstandard space for no good reason at all.
I also realize that removing the var will declare d on the global object, which is the expected behavior although it seems stupid to have var at the top level scope storing its values in a different place than "naked" variables. I mean, isn't the point of the module system supposed to be some sort of digital prophylactic to guard against global pollution? Here it seems so easy to break the pattern and so difficult to do something standard.
d is not declared on the module object either.
I don't have to justify why I'm asking this question but I'll answer the first troll to come along with a "but why do you want to do 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);
In the same way that I can differentiate between certain object states of d, I should be able to differentiate the states of the top level scope. In a browser this is the window object, referred to by this in the top level scope. I should be able to asses the properties of the environment before and after script execution to determine a great many things, one of which would be inspection of functions and variables declared in the top scope of an arbitrary script that they may then be applied to the exports object. This would make it easy to programatically generate module wrappers for scripts which were not written as modules with a simple forEach applied to the list of top level functions and variables to assign whateverThisIs['varFunc'] to module.exports['varFunc']...
and stuff...
This behavior appears to be like that of an anonymous function. In an anonymous function this could refer to the window object, vars would have to be called directly ( as they're in the anon func's scope ) and, leaked vars declared without the var keyword could end up at the window object. I haven't yet read the entire manual, maybe this is exactly what is going on but, I was under the impression that each module executed in it's own context (window) and that Node passed messages between module contexts through the use of global and module.exports...
I don't know. I want to know though. If you know, let me know.
So every node module is wrapped as the body of a function as shown here in the node source code
NativeModule.wrapper = [ '(function (exports, require, module, __filename, __dirname) { ', '\n});' ];
So if you declare a variable with var, it is function-local to the module, basically a private variable for that module. It is not a property of global, module, module.exports, or this. If you forget var, it goes into the global object as a property. If you explicitly create a property on this, that goes into exports and is available to other modules.
Here's a little program that is hopefully enlightening.
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);
And it's output:
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
这篇关于vars在Nodejs中存储在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!