1

一个初学者的问题,可能是一个微不足道的问题。这是 XUL 代码片段:

<window
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

    <script type="application/javascript" src="chrome://.../main.js"/>

    <button label="Click me!" oncommand="clickhandler()"/>
</window>

JavaScript 代码:

// main.js

var test = "Peanut butter";    // a global variable

function clickhandler() {
    alert(test);
}

解释器在读取主窗口的开始标记后立即处理 JavaScript 文件,然后继续处理其余的 XUL 代码。在我看来,test变量应该在解释器完成处理的那一刻就超出范围main.js。此外,该clickhandler()功能也应该超出范围,这意味着当单击按钮时,什么都不会发生。好吧,除非我将它们声明为document.testand document.clickhandler(),例如。然而,一个简单的实验证明我错了。单击按钮时,函数和变量都存在。像这样声明的变量的实际寿命是多少?它们什么时候被销毁?他们在应用程序退出之前一直存在吗?任何最佳实践和参考都受到高度赞赏。

4

2 回答 2

3

您期望它的行为类似于您习惯使用块作用域的语言。我建议通读 Douglas Crockford 的《The Good Parts》一书,以更好地理解为什么一切都会如此运作。如果您从一开始就了解所有这些,那么您将在以后的道路上轻松得多。

Javascript 在功能上是有作用域的。在这个例子中,测试的作用域在 foo 内部。

var foo = function() {
    var test = "Peanut Butter";
};

在此示例中,您可以看到该函数可以修改 test,因为它是一个全局范围的变量。

var test = "peanut butter";
var foo = function() {
    test = "Apple sauce";
};

有三种方法可以定义全局范围的变量,我建议您避免所有这些(并非完全,这是不可能的)。全局变量是必要的,但是可以减轻它们。它们的生命周期与加载 javascript 一样长。如果您在由同一页面加载的不同 .js 文件中定义多个全局变量,则这些全局变量都可以被两者访问,从而很容易意外地覆盖来自不同文件的 var。

1:就像你所做的那样,在任何函数之外放置一个 var 语句。

2:将其作为属性添加到全局对象。

window.foo = value;

3. 使用变量而不声明它,这是一个隐含的全局变量。真的要注意这些。您声明的函数实际上是一个隐含的全局本身,称为“clickhandler”。

foo = value;

最小化全局变量使用的一种常见做法称为全局消除,您可以在其中定义一个特定于应用程序的全局变量来保存其余的全局变量,以避免与其他库发生冲突。这是通过声明一个对象字面量并使用创建全局变量的第二种方法来完成的。但是,仅当您需要全局变量时才使用它,并尽可能坚持功能范围。

var AWESOMENEWAPP = {};
AWESOMENEWAPP.test = "Peanut Butter";

当您深入了解 javascript 的世界时,您将开始学习有用的东西,例如闭包等,以保持您的代码干净和有条理。

只是不要期望 javascript 像典型的经典语言一样工作,你会发现它本身就是一种强大的语言,只是不同。

On your journey, I suggest using the tool JSLint to test your code for following conventions and errors you won't see because it isn't compiled.

于 2012-04-10T21:36:41.937 回答
1

是的,如果您使用的是浏览器,全局函数和变量会一直存在,直到用户离开应用程序或关闭该选项卡。这就是为什么最好的做法是尽量不要在可能的情况下用变量或函数淹没全局范围。

于 2012-04-10T21:12:48.960 回答