如何在.js文件中声明全局变量

92

我需要一些全局变量,这些变量需要在所有.js文件中使用。

例如,考虑以下四个文件:

  1. global.js
  2. js1.js
  3. js2.js
  4. js3.js

如果我将上述4个文件全部加载到HTML文档中,是否有一种方法可以在global.js中声明三个全局变量,并在任何其他三个.js文件中访问它们?

请问是否有可能实现这一点或者是否有其他方法可以解决这个问题?

5个回答

98

只需在 global.js 文件中函数作用域外定义变量:

// global.js
var global1 = "I'm a global!";
var global2 = "So am I!";

// other js-file
function testGlobal () {
    alert(global1);
}
为了确保这个能够工作,你需要在访问该文件中定义的任何变量之前包含/链接到global.js:
<html>
    <head>
        <!-- Include global.js first -->
        <script src="/YOUR_PATH/global.js" type="text/javascript"></script>
        <!-- Now we can reference variables, objects, functions etc. 
             defined in global.js -->
        <script src="/YOUR_PATH/otherJsFile.js" type="text/javascript"></script>
    </head>
    [...]
</html>

如果你不想让js文件的加载中断初始页面加载,当然可以在闭合的<body>标签之前链接脚本标签。


4
虽然这个答案是正确的,但我建议你谷歌一下JavaScript变量作用域,以便更好地理解,可能避免以这种精确的方式处理事情。 - aleemb
1
同意。我总是尝试将所有函数和变量都放在一个公共的“命名空间”中,以避免混乱和冲突。通常我会用项目或公司的缩写来命名它。 - PatrikAkerstrand
对这个答案及其类似的答案进行负评,因为它假设全局变量将在全局范围内创建,并且要求变量的第一次提及在所有其他提及之前在全局范围内。 - Andrew
2
@Andrew 这个答案是八年前写的。当时来说,它是正确的。如果你想做出真正的贡献,建议你提出一个修改建议? - PatrikAkerstrand
@PatrikAkerstrand 实际上日期并不重要。其他使用全局对象的答案已经足够了;我解释了为什么这样做不好。 - Andrew
如果你使用 var,那么它怎么是全局的呢?你必须省略 var 才能使其成为全局的。 - Black

92

推荐的方法是:

window.greeting = "Hello World!"

然后您可以在任何函数中访问它:

function foo() {

   alert(greeting); // Hello World!
   alert(window["greeting"]); // Hello World!
   alert(window.greeting); // Hello World! (recommended)

}

这种方法有两个优点。

  1. 意图明确。使用var关键字很容易导致声明全局变量,而实际上想要的是局部变量,反之亦然。这种变量作用域的混淆是许多JavaScript开发人员的困惑点。因此,通常规则是,确保所有变量声明都在关键字var或前缀window之前。

  2. 你还可以标准化该语法以便以这种方式读取变量,这意味着局部作用域的var不会覆盖全局var,反之亦然。例如,在下面的代码中会发生什么是不明确的:

 

 greeting = "Aloha";

 function foo() {
     greeting = "Hello"; // overrides global!
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // does it alert "Hello" or "Howdy" ?

然而,这种方法更加简洁且不容易出错(您无需真正记住所有变量作用域规则):

 function foo() {
     window.greeting = "Hello";
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // alerts "Howdy"

将变量附加到窗口应在所有浏览器中正常工作(这也是我采取的方法,+1!)。 - Dandy
1
@Dan,如果你在函数外声明“var testvar ='hello';”,它会自动添加到window对象中,你可以使用“window.testvar”访问它。 - zkent
1
@zkent,没错,但是使用Window对象仍然更好,因为您可能希望将代码转换为类似咖啡的东西。 - NamiW
使用 Window 前缀比 Document 更好吗? - Andrew

7

你试过吗?

如果你试过:

var HI = 'Hello World';

global.js 中,然后执行:
alert(HI);

js1.js 中,它会正常弹出警告。你只需要在 HTML 文档中的其余部分之前包含 global.js 即可。
唯一的注意点是必须在 window 的范围内声明它(不在任何函数内)。
你可以取消 var 部分并以这种方式创建它们,但这不是一个好的做法。

7
如上所述,使用脚本文件中最高级别作用域存在问题。另一个问题是:在某些运行时环境中,脚本文件可能从非全局上下文运行。
有人建议将全局变量直接赋值给 window。但这也取决于运行时环境,并且在 Node 等环境中不起作用。这表明可移植的全局变量管理需要仔细考虑和额外的努力。也许他们会在未来的 ECMS 版本中解决这个问题!
目前,我建议像这样支持所有运行时环境的适当全局管理:
/**
 * Exports the given object into the global context.
 */
var exportGlobal = function(name, object) {
    if (typeof(global) !== "undefined")  {
        // Node.js
        global[name] = object;
    }
    else if (typeof(window) !== "undefined") {
        // JS with GUI (usually browser)
        window[name] = object;
    }
    else {
        throw new Error("Unkown run-time environment. Currently only browsers and Node.js are supported.");
    }
};


// export exportGlobal itself
exportGlobal("exportGlobal", exportGlobal);

// create a new global namespace
exportGlobal("someothernamespace", {});

多打一些字可能有些麻烦,但这样可以让您的全局变量管理具备未来可扩展性。

免责声明:我这个想法的部分灵感来源于之前版本的 stacktrace.js

我认为,也可以使用Webpack或其他工具来获取更可靠且不那么hackish的运行时环境检测。


2
GLOBAL 已经被弃用,应该使用 global - Thomas

2

是的,你可以访问它们。你应该在“公共空间”(任何函数之外)中声明它们:

var globalvar1 = 'value';

您可以稍后访问它们,也可以在其他文件中访问它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接