Are there constants in JavaScript?

后端 未结 30 2572
抹茶落季
抹茶落季 2020-11-22 08:53

Is there a way to use constants in JavaScript?

If not, what\'s the common practice for specifying variables that are used as constants?

相关标签:
30条回答
  • 2020-11-22 09:32

    Mozillas MDN Web Docs contain good examples and explanations about const. Excerpt:

    // define MY_FAV as a constant and give it the value 7
    const MY_FAV = 7;
    
    // this will throw an error - Uncaught TypeError: Assignment to constant variable.
    MY_FAV = 20;
    

    But it is sad that IE9/10 still does not support const. And the reason it's absurd:

    So, what is IE9 doing with const? So far, our decision has been to not support it. It isn’t yet a consensus feature as it has never been available on all browsers.

    ...

    In the end, it seems like the best long term solution for the web is to leave it out and to wait for standardization processes to run their course.

    They don't implement it because other browsers didn't implement it correctly?! Too afraid of making it better? Standards definitions or not, a constant is a constant: set once, never changed.

    And to all the ideas: Every function can be overwritten (XSS etc.). So there is no difference in var or function(){return}. const is the only real constant.

    Update: IE11 supports const:

    IE11 includes support for the well-defined and commonly used features of the emerging ECMAScript 6 standard including let, const, Map, Set, and WeakMap, as well as __proto__ for improved interoperability.

    0 讨论(0)
  • 2020-11-22 09:32

    You can easily equip your script with a mechanism for constants that can be set but not altered. An attempt to alter them will generate an error.

    /* author Keith Evetts 2009 License: LGPL  
    anonymous function sets up:  
    global function SETCONST (String name, mixed value)  
    global function CONST (String name)  
    constants once set may not be altered - console error is generated  
    they are retrieved as CONST(name)  
    the object holding the constants is private and cannot be accessed from the outer script directly, only through the setter and getter provided  
    */
    
    (function(){  
      var constants = {};  
      self.SETCONST = function(name,value) {  
          if (typeof name !== 'string') { throw new Error('constant name is not a string'); }  
          if (!value) { throw new Error(' no value supplied for constant ' + name); }  
          else if ((name in constants) ) { throw new Error('constant ' + name + ' is already defined'); }   
          else {   
              constants[name] = value;   
              return true;  
        }    
      };  
      self.CONST = function(name) {  
          if (typeof name !== 'string') { throw new Error('constant name is not a string'); }  
          if ( name in constants ) { return constants[name]; }    
          else { throw new Error('constant ' + name + ' has not been defined'); }  
      };  
    }())  
    
    
    // -------------  demo ----------------------------  
    SETCONST( 'VAT', 0.175 );  
    alert( CONST('VAT') );
    
    
    //try to alter the value of VAT  
    try{  
      SETCONST( 'VAT', 0.22 );  
    } catch ( exc )  {  
       alert (exc.message);  
    }  
    //check old value of VAT remains  
    alert( CONST('VAT') );  
    
    
    // try to get at constants object directly  
    constants['DODO'] = "dead bird";  // error  
    
    0 讨论(0)
  • 2020-11-22 09:35

    No, not in general. Firefox implements const but I know IE doesn't.


    @John points to a common naming practice for consts that has been used for years in other languages, I see no reason why you couldn't use that. Of course that doesn't mean someone will not write over the variable's value anyway. :)

    0 讨论(0)
  • 2020-11-22 09:36

    In JavaScript my practice has been to avoid constants as much as I can and use strings instead. Problems with constants appear when you want to expose your constants to the outside world:

    For example one could implement the following Date API:

    date.add(5, MyModule.Date.DAY).add(12, MyModule.Date.HOUR)
    

    But it's much shorter and more natural to simply write:

    date.add(5, "days").add(12, "hours")
    

    This way "days" and "hours" really act like constants, because you can't change from the outside how many seconds "hours" represents. But it's easy to overwrite MyModule.Date.HOUR.

    This kind of approach will also aid in debugging. If Firebug tells you action === 18 it's pretty hard to figure out what it means, but when you see action === "save" then it's immediately clear.

    0 讨论(0)
  • 2020-11-22 09:36

    JavaScript ES6 (re-)introduced the const keyword which is supported in all major browsers.

    Variables declared via const cannot be re-declared or re-assigned.

    Apart from that, const behaves similar to let.

    It behaves as expected for primitive datatypes (Boolean, Null, Undefined, Number, String, Symbol):

    const x = 1;
    x = 2;
    console.log(x); // 1 ...as expected, re-assigning fails
    

    Attention: Be aware of the pitfalls regarding objects:

    const o = {x: 1};
    o = {x: 2};
    console.log(o); // {x: 1} ...as expected, re-assigning fails
    
    o.x = 2;
    console.log(o); // {x: 2} !!! const does not make objects immutable!
    
    const a = [];
    a = [1];
    console.log(a); // 1 ...as expected, re-assigning fails
    
    a.push(1);
    console.log(a); // [1] !!! const does not make objects immutable
    

    If you really need an immutable and absolutely constant object: Just use const ALL_CAPS to make your intention clear. It is a good convention to follow for all const declarations anyway, so just rely on it.

    0 讨论(0)
  • 2020-11-22 09:38

    Introducing constants into JavaScript is at best a hack.

    A nice way of making persistent and globally accessible values in JavaScript would be declaring an object literal with some "read-only" properties like this:

                my={get constant1(){return "constant 1"},
                    get constant2(){return "constant 2"},
                    get constant3(){return "constant 3"},
                    get constantN(){return "constant N"}
                    }
    

    you'll have all your constants grouped in one single "my" accessory object where you can look for your stored values or anything else you may have decided to put there for that matter. Now let's test if it works:

               my.constant1; >> "constant 1" 
               my.constant1 = "new constant 1";
               my.constant1; >> "constant 1" 
    

    As we can see, the "my.constant1" property has preserved its original value. You've made yourself some nice 'green' temporary constants...

    But of course this will only guard you from accidentally modifying, altering, nullifying, or emptying your property constant value with a direct access as in the given example.

    Otherwise I still think that constants are for dummies. And I still think that exchanging your great freedom for a small corner of deceptive security is the worst trade possible.

    0 讨论(0)
提交回复
热议问题