Skip to content
📈0️⃣

多个 script 标签变量污染问题

案例

如果多个 script 标签中定义了相同名称的变量,那么这些变量会互相覆盖,甚至报错。

例如:多个 script 标签中同时定义了变量 const init = () => {},那么在任何一个脚本中尝试访问 init 变量都会导致错误。

错误写法

html
<script>
  const init = () => {};
</script>
<script>
  const init = () => {};
</script>

报错信息

js
`Uncaught SyntaxError: Identifier 'init' has already been declared`; 
`Uncaught SyntaxError: Identifier 'init' has already been declared`; 

解决方案

如果 init 函数在不同的 <script> 标签中定义,但是仍然出现了 Identifier 'init' has already been declared 的错误,那么可能是因为这两个 <script> 标签处于同一个作用域(全局作用域)下,导致函数重复声明。

在 HTML 页面中,所有位于全局作用域(即未包含在任何函数内部)的 <script> 标签中定义的函数和变量都属于相同的作用域。因此,在这种情况下,如果你在两个 <script> 中分别定义了相同名称的函数 init,就会触发该错误。

为避免这个问题,可以尝试以下解决方法:

  1. 合并到一个 <script> 标签中: 将两个 <script> 标签中的代码合并到一个标签中,确保函数只被声明一次。

  2. 使用模块化加载器: 如果您在使用模块化加载器(如 RequireJS、webpack 等),则每个模块有自己的作用域,可以避免全局作用域中的冲突。

  3. 命名空间: 在不同的 <script> 中使用命名空间(对象)来封装函数或变量,以防止命名冲突。

    javascript
    // 在第一个脚本中定义
    var myNamespace = myNamespace || {};
    myNamespace.init = function () {
      // 函数体
    };
    
    // 在另一个脚本中调用
    myNamespace.init();
  4. 立即执行函数: 使用立即执行函数来创建一个局部作用域,避免全局作用域中的冲突。

    javascript
    // 第一个脚本
    (function () {
      function init() {
        // 函数体
      }
    })();
    
    // 第二个脚本
    (function () {
      function init() {
        // 另一个函数体
      }
    })();