【问题标题】:JavaScript: Two separate scripts - share variables?JavaScript:两个独立的脚本——共享变量?
【发布时间】:2011-12-01 21:15:49
【问题描述】:

如果我在一个带有 JavaScript 的 HTML 页面中有两个单独的脚本,那么整个页面之间是否共享变量?还是只在他们自己的声明中?

例子:

<script> var title = "Hello World!"; </script>
// random HTML/PHP
<script> document.write(title); </script>

那会写“Hello World!”吗? 这似乎是糟糕的编码约定,我怎么能以适当的形式实现这样的目标。

【问题讨论】:

    标签: javascript coding-style


    【解决方案1】:

    您的示例中的变量标题被声明为全局变量,因此它可用于加载到同一页面中的任何和所有脚本。更重要的是,如果同一页面上已经有一个名为title的全局变量,当你给它赋值“Hello World!”时,它的值会被覆盖

    避免此类问题的通常做法是只声明一个全局变量,然后将所有其他变量放入其中。例如:

    var bobbyS_vars = {
        title: "Hello World!";
    };
    

    为这个唯一的全局变量分配一个其他人不可能选择的名称,例如您的姓名或雇主的名字,或者最重要的是,一个属于您或您的雇主的域名。

    处理这个问题的另一种更常见的方法是利用 JavaScript 处理函数内变量范围的方式。例如,创建一个匿名函数,在该函数中声明所有代码,然后通过在声明末尾放置 () 在声明末尾调用该函数。例如:

    (function() {
        var title = "Hello World!";
    
        document.write(title);
    })();
    
    // title is not in scope here, so it is undefined,
    // unless it were declared elsewhere.
    

    如果您想要共享一些变量,而不是其他变量,请让您的匿名函数使用多种方法:

    var bobbyS_vars = {
        title: "Hello World!";
    };
    
    (function() {
        var employeeId = "E 298";
        var count = 7;
    
        document.write("<p>" + bobbyS_vars.title + "</p>");
        document.write("<p>" + employeeId + "</p>");
    })();
    
    // At this point, bobbyS_vars.title is in scope and still has the 
    // value "Hello World!". Variables employeeId and count are not
    // in scope and effectively private to the code above.
    

    最后一点。您的代码声明的所有函数实际上也是全局变量。因此,如果您创建一个名为 printTitle 的函数,它 1) 可用于页面上的所有其他代码,并且 2) 可以覆盖或被同一页面上的另一个名为 printTitle 的函数覆盖。您可以像保护任何其他变量一样保护和/或公开您的函数:

    var bobbyS_vars = { };
    
    (function() {
        // Private functions
        var function = addOne(i) {
            return i + 1;
        };
    
        // Public vars
        bobbyS_vars.title: "Hello World!";
    
        // Public functions
        bobbyS_vars.printTitle = function() {
            document.write("<p>" + bobbyS_vars.title + "</p>");
            document.write("<p>" + addOne(41) + "</p>");
        };
    })();
    
    // At this point, function addOne is not directly accessible,
    // but printTitle is.
    bobbyS_vars.printTitle();
    

    请注意,虽然 addOne 函数实际上是闭包中的私有函数,但它仍然可以通过 printTitle 函数间接访问,因为 addOne 和 printTitle 都在同一范围内。

    【讨论】:

      【解决方案2】:

      title 位于 Global 范围内,对于在 Web 浏览器中运行的 JavaScript,它是 window 对象。当您在任何会限制其范围的函数之外说var title = "Hello World!" 时,它与说window.title = "Hello World!" 相同。您的代码相当于:

      <script>
          window.title = "Hello World!";
      </script> 
      <!-- random HTML/PHP -->
      <script>
          document.write(title);
          // or document.write(window.title) works just as well
      </script> 
      

      【讨论】:

      • 这部分回答了 OP 的问题,但没有提到如何避免这种模式。
      【解决方案3】:

      它们都将根据范围规则等“共享”。除了包含所述文件的顺序之外,单独的文件对此没有影响。

      编辑:同样的规则也适用于内联脚本。

      并详细说明异常:

      如果我有文件 Foo 我声明以下内容:

      var fooVar = barVar;

      然后我有文件 Bar 我声明以下内容:

      var barVar = 'bar';

      我按以下顺序包含它们:

      <script type="javascript/text" src="foo.js"></script>
      <script type="javascript/text" src="bar.js"></script>
      

      您将收到一个解释错误,因为 barVar 的使用出现在其声明之前。

      【讨论】:

        【解决方案4】:

        在这种情况下,title 将是一个全局变量。您需要将变量封装在范围内。有多种方法可以做到这一点。我的偏好是一个自动执行的匿名函数,可以这样完成:

            (function() {
               var title = "Hello world!";
        
               alert(title); // would pop up "Hello World!" since title is in scope
            });
        
            alert(title); // title doesn't exist, because it's outside the scope
        

        【讨论】:

          【解决方案5】:

          window 包含所有变量。所有脚本都在母 window 对象中。所以所有变量都在一个空间中。但是,它们可以本地化为函数等。

          【讨论】:

          • 不。 window 是全局范围,而不是 document
          • 请注意,window 对象是 Web 浏览器的全局范围上下文对象。在非浏览器环境中执行的 JavaScript 可能没有名为 window 的对象,但会有一个全局上下文对象。细节取决于环境。
          最近更新 更多