53

If so, what is the syntax for such a declaration?

Giffyguy
  • 20,378
  • 34
  • 97
  • 168
  • if by global you mean a variable that can be called after change on pages of the domain then what you need is cookies.. – crodjer Nov 13 '10 at 20:34
  • @Dcrodger: No, just global between functions. Also, this is a constant, not a variable - therefore cookies would be overkill. – Giffyguy Nov 13 '10 at 20:35
  • See also: http://stackoverflow.com/questions/130396/are-there-constants-in-javascript – Ken Nov 13 '10 at 21:19

10 Answers10

36

Javascript doesn't really have the notion of a named constant, or an immutable property of an object. (Note that I'm not talking about ES5 here.)

You can declare globals with a simple var declaration in the global scope, like outside any function in a script included by a web page:

<script>
  var EXACTLY_ONE = 1;

Then your code can use that constant of course, though it's not really "constant" because the value can be changed (the property updated, in other words).

edit — this is an ancient answer to an ancient question. In 2019, there's the const declaration that's supported just about everywhere. However note that like let, const scoping is different from var scoping.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 9
    Update - const keyword available in most modern browsers and standard in ES6 Harmony: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const – netpoetica Sep 26 '13 at 02:48
  • 2
    Do read the docs! const is limited to the scope, so something like: `if(DEBUG){const HOST = "locahost";} else { const HOST = "coolhost";}` won't expose `HOST` globally. – Robert Parcus May 18 '17 at 10:10
  • 1
    @RudolfCicko well it'd be `writable: false, enumerable: false` probably; there's no "readOnly" – Pointy Dec 02 '19 at 12:43
  • 1
    @Pointy Aww yeah you are right.. `Object.defineProperty(window, 'CONST_ATTR', { value: 'UNCHANGEABLE_VALUE' });` would work because `writable: false` is by default. – Rudy Dec 02 '19 at 13:38
31

As "Pointy" so carefully notes, ECMAscript has no such feature. However, JavaScript does:

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

Of course, if you're writing code to put on the web to run in web browsers, this might not help you much. :-)

Ken
  • 756
  • 4
  • 7
  • 5
    Why on earth has this been downvoted? It's true, not well-known and useful if you're working in a Mozilla-only environment. +1 from me. – Tim Down Nov 14 '10 at 00:34
  • 6
    @Tim, was down-voted by someone that doesn't knows the difference between ECMAScript and JavaScript(tm)..., +1 also from me... BTW One thing to keep in mind, is that the TC39 committee has approved a set [recommendations for implementors](http://j.mp/agMtti), that include restrictions on non-standard declarations -as `const`- on strict mode code. Firefox 4 at the moment has no restrictions about non-standard declarations under strict mode, but WebKit's JavaScriptCore has them -really good thing IMO-, you can't use `const` or have `FunctionDeclarations` inside `Blocks`... just to keep in mind.. – Christian C. Salvadó Nov 14 '10 at 02:40
  • @CMS: Interesting, I hadn't looked into that. Thanks. – Tim Down Nov 14 '10 at 11:29
  • Perhaps the answer is being down voted because it does not answer the question of globality. – kojow7 Jan 29 '18 at 21:17
24

Everything is global unless declared with the var keyword.

There are no constants either. You can simply declare them without the var keyword.

If you want to ensure global scope you can throw it into the window object:

window.GLOBAL_CONSTANT = "value";

You can do this from within any scope. Constants can then be declared inside functions or closures, though I wouldn't recommend that.

Josh K
  • 28,364
  • 20
  • 86
  • 132
  • if you remove the var keyword, you get an undefined error in strict mode. –  Feb 14 '19 at 12:06
  • 2
    You may want to edit to talk about strict mode, other environments (such as nodejs, which uses ```global``` instead of ```window```), ```new Function("return this")()```, and ```globalThis``` – ecc521 Jul 10 '19 at 17:30
17

If you only care about supporting newer browsers (or are using a transpiler such as Babel to support older browsers) you can do the following:

  1. Create a settings.js file with whatever constants you want and export them:
export const FRUIT = "kiwi";
export const VEGETABLE = "carrot";
  1. In files that you want to use them you could then import them as follows:
import * as Settings from './settings.js'
  1. Then to use the constants do something like this:
console.log("The unchangeable fruit is " + Settings.FRUIT);

This is a much cleaner approach than trying to implement a global constant, especially when you have multiple JavaScript files that you want to use the constants in.

kojow7
  • 10,308
  • 17
  • 80
  • 135
10

You could do it with getters and setters like so:

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

If you want a general function to do this:

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);
Basic Block
  • 729
  • 9
  • 17
  • 3
    +1 for using getters and setters (which should allow code not in the global scope to define constant globals). You may want to edit to talk about strict mode, other environments (such as nodejs, which uses ```global``` instead of ```window```), ```new Function("return this")()```, and ```globalThis```. – ecc521 Jul 10 '19 at 17:31
3

If you want to make sure the value cannot change use a function.

So, instead of:

var Const_X=12

use:

function Const_X() {
return 12;
}
Joe
  • 7,113
  • 1
  • 29
  • 34
leon
  • 31
  • 1
3

The direct answer to the question is No. It would really help though if ECMA/JS made a way to easily do functional programming. A workable hack I use to get around this is to declare a const in the global scope and use a wrapper function see example below:

:)

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);

:)

Way back when object oriented programming was the hype a kid in my class told the C instructor that C isn't object oriented to which the instructor said he's done object oriented programming in C before Java and C++ were even conceived. Likewise you can do functional programming in Javascript but its much harder. Its like doing Object-oriented programming in C when its easier to do it in C++.

1

For the record.

// 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.

So, if the constant is defined inside {} then it's local, otherwise, it's global.

magallanes
  • 6,583
  • 4
  • 54
  • 55
0

Similar to kojow7's answer, but instead of using grabbing all named exports I like to use one named export e.g. Constants and then declare my constants like this:

  1. Create a Constants.js file with declaring your constants like this and export Constants:
// Constants.js
export const Constants = {
  FRUIT: "kiwi",
  VEGETABLE: "carrot",
};
  1. Make a named import in the files you need a constant:
import { Constants } from './Constants';
  1. Then use the constants as follows:
console.log("The unchangeable fruit is " + Constants.FRUIT);

There seems to be no downfall to use the one over the other option, but what I like personally is that I just name the file as I want to import it import { Constants } from './Constants'; and not always think about how I call it when grabbing all named exports import * as Constants from './Constants'. So in the second case I might want to look in another file where I imported already the constants and look how I named the import in case of consistency. Have a look also here for the different export/import possibilities.

ronatory
  • 7,156
  • 4
  • 29
  • 49
-1

If you're not planning to change the value of any object properties, you can use Object.freeze():

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

The following demonstrates the difference between const and Object.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);
Antonio Ooi
  • 1,601
  • 1
  • 18
  • 32