如何在JavaScript中声明常量(即使它在JavaScript中不存在)

5
简而言之,我有一个模块,希望在页面上多次重复使用。在这个模块中,我有一个全局常量事件名称。问题出现在第二次使用此模块的声明中,因为常量已经被声明。但是,我不能将其移动到 if/else 中,因为作用域会使常量无法在其他地方使用。我该怎么办?
一些简单的代码来说明我的问题:
模块:
const THIS_IS_MY_EVENT = 'thisIsMyEvent';

// extra code down here

页面:(我使用Twig引擎来包含文件,但我不认为它与此有关)

<script src="/path/to/file.js">
<script src="/path/to/file.js">

这种方法在我的情况下肯定行不通:

if (typeof (THIS_IS_MY_EVENT) == undefined) {
    const .... //this will limit the scope of my const
}

非常感谢您的帮助。


1
如果我理解正确的话,那么将 const 存储在常量文件中,并在每个模块中导入它怎么样? - YarinDekel
@YarinDekel 那有什么不同吗?由于您导入了两次模块,因此您仍将两次导入常量文件到页面中。在您的情况下,我看到的解决方法是将所有常量设置在一个文件中,并直接将其导入页面。但是,这有点混乱,以我的意见为主。 - Tree Nguyen
2
@TreeNguyen,您可能误解了导入的工作方式。模块会被缓存,内部代码仅会运行一次。 - Matt Way
@MattWay 抱歉,不是那样的。我想我的术语用错了。在我的情况下,模块=可重复使用的代码片段。它不是任何意义上的类,也没有导入或导出。通过使用twig,它基本上是将文件复制粘贴到文件中。所以我写的“模块”被插入到同一页两次。 - Tree Nguyen
3
是的,这完全违背了 const 的用途,而且并不是一种解决方案,只是一种权宜之计,直到你实现 T.J. Crowder 的答案。 - RobG
显示剩余2条评论
1个回答

3
简而言之,我有一个模块,希望在页面上多次重复使用它。这听起来像是要解决的真正问题。相反,只需导入模块一次,在其中使用一个函数两次。通常情况下,模块在导入时不应该执行任何操作(除了进行一些设置),只有在需要时才会执行。这样,模块的全局部分将运行一次,创建全局的const(但它不应该是全局的,应该是从模块中导出的const),这样你就不会遇到问题了。
但条件地创建全局常量是一个有趣的问题。如果你真的想要一个全局变量,可以使用Object.defineProperty在window上创建它,并使用writable: false。 (这并不完全相同。 window上的属性是全局的,但const创建的全局不是window的属性。 但是,可能已经足够接近了。)
示例:

"use strict";
if (typeof THIS_DOESNT_EXIST === "undefined") {
  Object.defineProperty(window, "THIS_DOESNT_EXIST", {
    value: "foo",
    writable: false,     // false is the default
    configurable: false, // these are just for emphasis,
    enumerable: true     // or false, your call
  });
}
console.log(THIS_DOESNT_EXIST);
THIS_DOESNT_EXIST = 42;
console.log(THIS_DOESNT_EXIST);


我真的需要它全局化,因为我使用这个常量来触发事件并监听它。 - Tree Nguyen
2
@TreeNguyen - 这不符合逻辑。如果您正确使用模块,就不需要任何全局变量。 - T.J. Crowder
嗨,正如我在上面的评论中提到的那样。我确实认为我的术语不正确。在我的情况下,模块=可重用代码片段。它不是任何意义上的类,也没有导入或导出。通过使用twig,它基本上是将文件复制粘贴到文件中。所以我写的“模块”被插入到同一页两次。而且在这两个模块中,代码有点不同。 - Tree Nguyen
1
@TreeNguyen - 在你的问题中,你展示了两次加载同一个文件,因此代码不可能不同。如果你确实要加载可能创建相同常量的两个单独的文件,请不要这样做。相反,有一个仅创建常量并且只需加载一次(在其他文件之前或同时)的单个文件。或者退一步,切换到使用正确的模块;这些问题正是为什么创建模块的原因。 - T.J. Crowder
1
你说得对。在向你陈述问题后,我意识到这个问题很棘手,没有任何解决方案能够解决它。我会退一步,寻找更合适的方法。 - Tree Nguyen

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