Nodejs和隐式全局变量?

时间:2014-06-18 21:18:12

标签: node.js

我使用了一些打算在浏览器中使用的外部库,他们隐式设置全局变量,如a =' a' (没有var)。

似乎当我需要某些脚本执行此操作时,有时变量将在其范围之外可访问,就像在浏览器中一样,但对于其他脚本,全局变量不能在其自己的脚本之外访问。

任何人都知道nodejs如何处理隐式全局变量,以及为什么我会看到一些随机行为?我在互联网上发现了很少的东西。

我可以进入脚本。写点像

if(typeof exports !== 'undefined' && this.exports !== exports){
            var GLOBAL=global;
        }
        else{
                var GLOBAL=window;
            }

然后更改对GLOBAL.reference的所有隐式引用,但这些脚本不是我自己的,每次我想要获取它们的最新版本时我都要再做一遍,这显然是不可取的。

使用module.exports会更干净,因为我没有更改所有引用,只是添加导出全局变量的每个文件顶部的一部分,但我原来的问题是关于节点如何处理隐式全局变量仍然相关

3 个答案:

答案 0 :(得分:1)

我不确定这个答案是否会对您有所帮助,因为很难诊断您的代码发生了什么,但也许有些推理可以帮助您诊断代码中的实际问题。

节点中的行为实际上与浏览器的行为类似。如果您要声明不带var关键字的变量,则可以通过global对象访问该变量。

//module foo.js
a = 'Obi-wan';

//module bar.js
require('./foo');
console.log(global.a); //yields Obi-wan
console.log(a); //yields Obi-wan

目前尚不清楚为什么你说这种行为在你的代码中是不一致的,但是如果你考虑一下,全局变量的使用正是受到这类问题的影响,因为它们是全局的,每个人都可以在任何地方覆盖它们。时间,导致这种意外情况。

有一个方面,节点与浏览器不同,这可能会影响您看到的行为。

在浏览器中,如果您直接在JavaScript文件中执行此类操作:

console.log(this==window); //yields true

但是如果你在Node.js模块中做同样的事情:

console.log(this==global); //yields false

基本上,在Node.js模块的外部范围内,this引用指向当前的module.exports对象。

console.log(this==exports); //yield true

因此,如果您通过使用this将数据放入浏览器的全局范围(窗口)中,则可能会在Node.js中找到模块范围。

有趣的是,就使用全局范围而言,Node.js中函数内部的代码与浏览器中的代码非常相似。

(function what(){
   console.log(this==global); //yields true
})();

答案 1 :(得分:0)

这并没有直接回答你的问题,但它提供了一个解决方案,因为我认为不可能。

我喜欢正则表达式。他们是如此强大:

js = js.replace(/^(\t|\s{4})?(var\s)?(\w+)\s=/gm, function () {
    if (arguments[1] || arguments[2]) return (arguments[1] || '') + (arguments[2] || '')  + arguments[3] + ' =';
    return 'exports.' + arguments[3] + ' =';
});*

JSFiddle here

它是如何工作的?我会回溯我的工作:

  1. /(\w+)\s=/g将获取任何var,return 'exports.' + arguments[1] + ' =';会将其转换为导出。不太好。
  2. /(var\s)?(\w+)\s=/g将接受任何var,但在回调中我们检查了第一组(var\s)。这是不确定的?然后我们应该导出它,否则什么都不应该发生。但是范围怎么样?
  3. /^(\t|\s{4})?(var\s)?(\w+)\s=/gm现在我们使用缩进来确定范围:)
  4. 您应该能够在您的文件上运行此正则表达式。要小心,你需要正确缩进,并注意我可能忘记了一些事情。

答案 2 :(得分:0)

啊,问题是在浏览器中全局声明的全局变量未通过=' a'声明,但是var a =' a&# 39 ;.在浏览器中,如果var关键字不在函数内使用,它仍将声明一个全局变量。如果var关键字在函数内,它只声明一个局部变量。 Node.js不会以这种方式运行,并且所有var声明都被认为是本地的。

它的ashame node.js这样做,它使它与浏览器脚本的兼容性降低,没有真正的原因。 (除了允许人们不必将所有脚本包装在函数中)。