【问题标题】:Can global constants be declared in JavaScript?可以在 JavaScript 中声明全局常量吗?
【发布时间】:2011-05-09 15:23:43
【问题描述】:

如果是这样,这种声明的语法是什么?

【问题讨论】:

  • 如果全局是指一个可以在域页面更改后调用的变量,那么您需要的是 cookie..
  • @Dcrodger:不,只是函数之间的全局。此外,这是一个常数,而不是一个变量 - 因此 cookie 将是多余的。

标签: javascript variables constants global-variables


【解决方案1】:

类似于kojow7's answer,但不是使用抓取所有命名导出,我更喜欢使用一个命名导出,例如Constants 然后像这样声明我的常量:

  1. 创建一个 Constants.js 文件,像这样声明您的常量并导出 Constants
// Constants.js
export const Constants = {
  FRUIT: "kiwi",
  VEGETABLE: "carrot",
};
  1. 在需要常量的文件中进行命名导入:
import { Constants } from './Constants';
  1. 然后按如下方式使用常量:
console.log("The unchangeable fruit is " + Constants.FRUIT);

使用一个选项似乎没有失败,但我个人喜欢的是我只是将文件命名为我想导入它import { Constants } from './Constants';,而不是总是考虑我在抓取时如何称呼它所有命名的导出import * as Constants from './Constants'。因此,在第二种情况下,我可能想查看另一个文件,其中我已经导入了常量,并查看我如何命名导入以确保一致性。还请查看 here 以了解不同的导出/导入可能性。

【讨论】:

    【解决方案2】:

    如果您不打算更改任何对象属性的值,可以使用Object.freeze()

    window.globalConst = Object.freeze( { x: 1, y: true } );
    

    下面演示constObject.freeze()的区别:

    const x = Object.freeze({
      a: 1,
      b: 2
    });
    
    x.a = 3;
    
    // x.a is still = 1
    console.log("x.a = ", x.a);
    
    const y = {
      a: 1,
      b: 2
    };
    
    y.a = 3;
    
    // y.a has been changed to 3
    console.log("y.a = ", y.a);

    【讨论】:

      【解决方案3】:

      Javascript 并没有真正意义上的命名常量或对象的不可变属性。 (请注意,我在这里不是在谈论 ES5。)

      您可以在全局范围内使用简单的var 声明来声明全局变量,就像在网页包含的脚本中的任何函数之外一样:

      <script>
        var EXACTLY_ONE = 1;
      

      然后您的代码当然可以使用该常量,尽管它并不是真正的“常量”,因为值可以更改(换句话说,属性已更新)。

      edit——这是对一个古老问题的古老答案。在 2019 年,几乎所有地方都支持 const 声明。但是请注意,像 letconst 的作用域不同于 var 的作用域。

      【讨论】:

      • 更新 - 大多数现代浏览器中可用的 const 关键字和 ES6 Harmony 中的标准:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
      • 请阅读文档! const 仅限于范围,因此类似:if(DEBUG){const HOST = "locahost";} else { const HOST = "coolhost";} 不会在全球范围内公开HOST
      • @RudolfCicko 可能是writable: false, enumerable: false;没有“只读”
      • @Pointy Aww 是的,你是对的。Object.defineProperty(window, 'CONST_ATTR', { value: 'UNCHANGEABLE_VALUE' }); 可以工作,因为writable: false 是默认设置。
      【解决方案4】:

      记录在案。

      // ES6+ code:
      const CONSTGLOBAL1=200;  // it is a constant global
      
      function somef() { 
         document.write(CONSTGLOBAL1); // CONSTGLOBAL1 is defined (because it's global)
         const CONSTLOCAL=200; // it's a local constant
         document.write(CONSTLOCAL); // CONSTLOCAL is defined
      }       
      somef();
      document.write(CONSTLOCAL); // CONSTLOCALis NOT defined.
      

      所以,如果常量是在 {} 中定义的,那么它就是本地的,否则就是全局的。

      【讨论】:

        【解决方案5】:

        你可以像这样使用 getter 和 setter 来做到这一点:

        Object.defineProperty(window, 'TAU', { 
            get: function(){return Math.PI*2;}
        });
        

        如果你想要一个通用函数来做到这一点:

        function define(name, value){
            Object.defineProperty(window, name, { 
               get: function(){return value;},
               set: function(){throw(name+' is a constant and cannot be redeclared.');},
            });
        }
        
        // Example use
        define('TAU', Math.PI*2);
        

        【讨论】:

        • +1 用于使用 getter 和 setter(这应该允许不在全局范围内的代码定义常量全局变量)。您可能想编辑讨论严格模式、其他环境(例如 nodejs,它使用 global 而不是 window)、new Function("return this")()globalThis
        【解决方案6】:

        这个问题的直接答案是否定的。不过,如果 ECMA/JS 提供了一种轻松进行函数式编程的方法,那将真的很有帮助。我用来解决这个问题的一个可行技巧是在全局范围内声明一个 const 并使用包装函数,请参见下面的示例:

        :)

        global_var = 3; //This can change say inside a function etc. but once you decide to make 
                        //this global variable into a constant by calling on a function
        const make_variable_constant = function(variable)
        {
            const constant = variable;
            return constant;
        }
        
        const const_global = make_variable_constant(global_var);
        

        :)

        当面向对象编程是大肆宣传时,我班上的一个孩子告诉 C 讲师 C 不是面向对象的,讲师说他甚至在 Java 和 C++ 出现之前就已经用 C 完成了面向对象编程。同样,您可以在 Javascript 中进行函数式编程,但要困难得多。它就像在 C 中进行面向对象编程一样,而在 C++ 中更容易做到这一点。

        【讨论】:

          【解决方案7】:

          如果您只关心支持较新的浏览器(或正在使用诸如 Babel 之类的转译器来支持较旧的浏览器),您可以执行以下操作:

          1. 使用您想要的任何常量创建一个 settings.js 文件并导出它们:
          export const FRUIT = "kiwi";
          export const VEGETABLE = "carrot";
          
          1. 在您想使用它们的文件中,您可以按如下方式导入它们:
          import * as Settings from './settings.js'
          
          1. 然后使用常量执行如下操作:
          console.log("The unchangeable fruit is " + Settings.FRUIT);
          

          与尝试实现全局常量相比,这是一种更简洁的方法,尤其是当您有多个要在其中使用常量的 JavaScript 文件时。

          【讨论】:

            【解决方案8】:

            如果您想确保值不能更改,请使用函数。

            所以,而不是:

            var Const_X=12
            

            使用:

            function Const_X() {
            return 12;
            }
            

            【讨论】:

            • 旧答案,但我很确定您可以覆盖函数。
            【解决方案9】:

            正如“Pointy”如此仔细地指出的那样,ECMAscript 没有这样的功能。但是,JavaScript does

            const a = 7;
            document.writeln("a is " + a + ".");
            

            当然,如果您正在编写代码以在网络上运行以在网络浏览器中运行,这可能对您没有多大帮助。 :-)

            【讨论】:

            • 为什么这被否决了?如果您在仅 Mozilla 的环境中工作,这是真的,不是众所周知且有用的。来自我的 +1。
            • @Tim,被不知道 ECMAScript 和 JavaScript(tm) 之间区别的人投了反对票……,我也 +1……顺便说一句要记住的一件事,是 TC39 委员会批准了一组recommendations for implementors,其中包括对非标准声明的限制 - 如const- 严格模式代码。 Firefox 4 目前对严格模式下的非标准声明没有任何限制,但是 WebKit 的 JavaScriptCore 有它们 - 真的是 IMO 的好东西 - 你不能使用 const 或在 Blocks 中使用 FunctionDeclarations... 只是要记住..
            • @CMS:有趣,我没有研究过。谢谢。
            • 也许答案被否决了,因为它没有回答全球性问题。
            【解决方案10】:

            除非使用 var 关键字声明,否则一切都是全局的。

            也没有常数。您可以简单地声明它们而不使用 var 关键字。

            如果你想确保全局范围,你可以把它扔到window对象中:

            window.GLOBAL_CONSTANT = "value";
            

            您可以在任何范围内执行此操作。然后可以在函数或闭包中声明常量,但我不建议这样做。

            【讨论】:

            • 如果你去掉 var 关键字,你会在严格模式下得到一个未定义的错误。
            • 您可能想要编辑讨论严格模式、其他环境(例如 nodejs,它使用global 而不是window)、new Function("return this")()globalThis
            猜你喜欢
            • 2020-03-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-01
            • 1970-01-01
            • 2021-10-02
            • 2020-06-27
            • 1970-01-01
            • 2013-09-20
            相关资源
            最近更新 更多