当前位置:  开发笔记 > 编程语言 > 正文

JavaScript中是否有常量?

如何解决《JavaScript中是否有常量?》经验,为你挑选了19个好方法。

有没有办法在JavaScript中使用常量?

如果没有,指定用作常量的变量的常见做法是什么?



1> John Milliki..:

自ES2015以来,JavaScript有一个概念const:

const MY_CONSTANT = "some-value";

除了IE 8,9和10之外,这几乎适用于所有浏览器.有些可能还需要启用严格模式.

您可以使用varALL_CAPS等约定来显示如果您需要支持旧版浏览器或使用旧代码,则不应修改某些值:

var MY_CONSTANT = "some-value";


请注意,如果您不需要跨浏览器兼容性(或者您在Rhino或Node.js中进行服务器端编程),则可以使用`const`关键字.目前除了IE之外,所有现代浏览器都支持它.
const x = 24怎么样;
由于谷歌在2015年的答案仍然排名很高,应该说它已经过时了.`const`关键字现在正式成为该语言的一部分,并得到每个浏览器的支持.根据statcounter.com,只有百分之几的互联网用户仍然使用不支持`const`的旧浏览器版本.
这些天(3.5年后)你可以使用[`Object.defineProperty`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty)来创建也可以'的只读属性'被删除.这适用于所有主流浏览器的当前版本(但[在IE8中不正确](http://stackoverflow.com/questions/4819693/working-around-ie8s-broken-object-defineproperty-implementation)).请参阅@NotAName的答案
@Amyth那不是很有帮助.这是由唯一供应商提出的风格**指南**.根据赫斯基的观点,在编写服务器端JS时,IE兼容性完全无关紧要.
@dngfng 6年后,除了IE10和更早版本之外,所有浏览器都支持const.
@ Dr.Zim:根据编码标准,你不应该使用`const`关键字,因为它在Internet Explorer中不受支持.参考:http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Constants#Constants
这是一个“天真”的答案,只能通过重新分配来作为“ const” __ prevents__!您可以执行以下操作:`const x = {a:1};`,然后`xa = 2;`注意!要使常量成为常量,可以使用:const x = Object.freeze({a:1});`

2> 小智..:

您是否试图保护变量不被修改?如果是这样,那么您可以使用模块模式:

var CONFIG = (function() {
     var private = {
         'MY_CONST': '1',
         'ANOTHER_CONST': '2'
     };

     return {
        get: function(name) { return private[name]; }
    };
})();

alert('MY_CONST: ' + CONFIG.get('MY_CONST'));  // 1

CONFIG.MY_CONST = '2';
alert('MY_CONST: ' + CONFIG.get('MY_CONST'));  // 1

CONFIG.private.MY_CONST = '2';                 // error
alert('MY_CONST: ' + CONFIG.get('MY_CONST'));  // 1

使用此方法,无法修改值.但是,你必须在CONFIG上使用get()方法:(.

如果您不需要严格保护变量值,那么只需按照建议执行并使用ALL CAPS约定.


`CONFIG.get = someNewFunctionThatBreaksTheCode` ...总而言之,你绝对不能在JS(w/o const关键字)中强制执行常量.你唯一能做的就是限制能见度.
我相信`private`是JavaScript中未来的保留词,如果我是你,我不会使用它.
请注意,您只需返回CONFIG值的函数即可.这样可以节省你一直调用CONFIG.get()的时间.
漂亮的解决方 但是这些东西应该被包装成一个库,不要在任何新项目中重新发明它们.

3> Bill the Liz..:

const关键字是ECMAScript的第6条草案,但迄今只享受的浏览器支持一知半解:http://kangax.github.io/compat-table/es6/.语法是:

const CONSTANT_NAME = 0;


如果您尝试将值赋给`const`,则不会抛出任何错误.赋值失败,常量仍然具有原始值.这是一个主要的设计缺陷恕我直言,但只要有一个明确,一致的命名约定(如流行的ALL_CAPS),我不认为这会导致太多的悲伤.
请关注浏览器支持:http://kangax.github.io/es5-compat-table/es6/#const
@MatrixFrog赋值将使用''use strict'`引发错误.

4> sam..:
"use strict";

var constants = Object.freeze({
    "?": 3.141592653589793 ,
    "e": 2.718281828459045 ,
    "i": Math.sqrt(-1)
});

constants.?;        // -> 3.141592653589793
constants.? = 3;    // -> TypeError: Cannot assign to read only property '?' …
constants.?;        // -> 3.141592653589793

delete constants.?; // -> TypeError: Unable to delete property.
constants.?;        // -> 3.141592653589793

请参见Object.freeze.如果您想将引用设置为只读,也可以使用constconstants.


应该提到这只适用于IE9 + http://kangax.github.io/compat-table/es5/.

5> 小智..:

IE确实支持常量,例如:




男孩,谈论不是跨浏览器的事情...在开箱即用的时候还是+1.
VBScript的?那是什么?;)
我通常使用IE特定答案向一般相关的跨浏览器问题投票.因为我讨厌那些认为IE javascript实现是'One'的人,而其他人只是被忽略了.谁比IE使用其他的borwsers,顺便说一下?

6> Not a Name..:

ECMAScript 5确实介绍了Object.defineProperty:

Object.defineProperty (window,'CONSTANT',{ value : 5, writable: false });

每个现代浏览器都支持它(以及IE≥9).

另请参阅:ES5中的Object.defineProperty?


你实际上可以省略`writable:false`,因为那是[default](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty).
我最近读到,如果在ECMAScript 5的严格模式下解释执行赋值的代码,则尝试使用`writable:false`*分配属性将*实际抛出错误.将"使用严格"写入代码的另一个原因.

7> Jason Buntin..:

不,不是一般的.Firefox实现,const但我知道IE没有.


@John指出了在其他语言中使用多年的竞争的常见命名实践,我认为没有理由不能使用它.当然,这并不意味着有人不会写出变量的值.:)


众所周知,如果IE没有实现它,它可能也不存在.
不幸的是,实际上 - 这是事实.IE确实占有很大的市场份额.如果我拥有一家企业并且内部使用了Web应用程序,那么我会对FF进行标准化.我不知道为什么这么多人关心IE,它会受到打击.

8> mgutt..:

Mozillas MDN Web Docs包含很好的例子和解释const.摘抄:

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

但令人遗憾的是,IE9/10仍然不支持const.这是荒谬的原因:

那么,IE9用const做什么呢?到目前为止,我们的决定一直是不支持它.它还不是一个共识功能,因为它从未在所有浏览器上都可用.

...

最后,对于网络而言,最好的长期解决方案似乎是将其排除在外并等待标准化流程运行.

他们没有实现它,因为其他浏览器没有正确实现它?!太害怕让它变得更好?标准定义与否,常数是常数:设置一次,永不改变.

对于所有想法:每个功能都可以被覆盖(XSS等).所以在var或没有区别function(){return}.const是唯一真正的常数.

更新:IE11 支持 const:

IE11包括用于新兴的ECMAScript 6标准包括割舍的明确定义和常用的功能支持,const,Map,Set,和WeakMap,以及__proto__改进的互操作性.


"它从未在所有浏览器上都可用".如果你没有在IE中使用它,它将永远不会在所有浏览器中.

9> 小智..:

在JavaScript中,我的首选是使用函数来返回常量值.

function MY_CONSTANT() {
   return "some-value";
}


alert(MY_CONSTANT());


-1.这与var SOME_NAME = value(它仍然是可变的)没有任何好处,代码更多,需要解释.
值得指出的是,这与@Burkes的回答(@trithithis的评论)中提到的问题相同.`MY_CONSTANT = function(){return"some-other-value"; 打破它.虽然+1,体面和快速的解决方案.

10> tenshou..:

使用"new"Object api,您可以执行以下操作:

var obj = {};
Object.defineProperty(obj, 'CONSTANT', {
  configurable: false
  enumerable: true,
  writable: false,
  value: "your constant value"
});

看看这对Mozilla的MDN的更多细节.它不是第一级变量,因为它附加到一个对象,但如果你有一个范围,任何东西,你可以将它附加到它.this也应该工作.因此,例如在全局范围内执行此操作将在窗口上声明一个伪常量值(这是一个非常糟糕的主意,您不应该不小心声明全局变量)

Object.defineProperty(this, 'constant', {
  enumerable: true, 
  writable: false, 
  value: 7, 
  configurable: false
});

> constant
=> 7
> constant = 5
=> 7

注意:赋值将返回控制台中指定的值,但变量的值不会更改


不是'没有在野生动物园工作',而是在野生动物园中没有_supported_.不一样.它应该抛出一个'未捕获的TypeError:无法重新定义属性:'如果您尝试这样做.要么你做错了,要么你的ff错误地实现了它.我猜这是两者的混合.

11> hasen..:

如果您不介意使用功能:

var constant = function(val) {
   return function() {
        return val;
    }
}

这种方法为您提供了函数而不是常规变量,但它保证*一旦设置了值,任何人都无法改变它.

a = constant(10);

a(); // 10

b = constant(20);

b(); // 20

我个人认为这很令人愉快,特别是在从淘汰观察中习惯了这种模式之后.

*除非有人constant在你打电话之前重新定义了这个功能


这从来没有真正对我有用.即使闭包使其不可变,您分配给它的var仍然可以被覆盖.例如:`a =常数(10); 一个(10); // 10`后跟`a = constant(25); 一个(); // 25`,没有给出错误或警告,没有迹象表明你的常数已被打破.

12> Manohar Redd..:

在可能的情况下将常量分组为结构:

例如,在我目前的游戏项目中,我使用了以下内容:

var CONST_WILD_TYPES = {
    REGULAR: 'REGULAR',
    EXPANDING: 'EXPANDING',
    STICKY: 'STICKY',
    SHIFTING: 'SHIFTING'
};

分配:

var wildType = CONST_WILD_TYPES.REGULAR;

比较:

if (wildType === CONST_WILD_TYPES.REGULAR) {
    // do something here
}

最近我使用,比较:

switch (wildType) {
    case CONST_WILD_TYPES.REGULAR:
        // do something here
        break;
    case CONST_WILD_TYPES.EXPANDING:
        // do something here
        break;
}

IE11采用新的ES6标准,具有'const'声明.
以上工作在早期的浏览器,如IE8,IE9和IE10.



13> 小智..:

您可以轻松地为脚本配备一个可以设置但不能更改的常量机制.尝试更改它们将产生错误.

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



14> Derek 朕會功夫..:

忘记IE并使用const关键字.


适合我!但后来我正在写一个chrome扩展,所以我知道我是一个理智的浏览器......

15> Sudhanshu Ya..:

然而,没有确切的跨浏览器预​​定义方法来实现它,您可以通过控制变量的范围来实现它,如其他答案所示.

但我建议使用名称空间来区分其他变量.这样可以将碰撞的几率从其他变量降到最小.

正确的命名空间就像

var iw_constant={
     name:'sudhanshu',
     age:'23'
     //all varibale come like this
}

因此,使用它将是iw_constant.nameiw_constant.age

您还可以使用Object.freeze方法阻止添加任何新密钥或更改iw_constant中的任何密钥.但是旧版浏览器不支持它.

例如:

Object.freeze(iw_constant);

对于旧版浏览器,您可以使用polyfill进行冻结方法.


如果你可以调用函数,那么最好用跨浏览器的方式来定义常量.在自执行函数中确定对象的范围,并为常量返回get函数:

var iw_constant= (function(){
       var allConstant={
             name:'sudhanshu',
             age:'23'
             //all varibale come like this

       };

       return function(key){
          allConstant[key];
       }
    };

//获取值使用 iw_constant('name')iw_constant('age')


**在这两个示例中,您必须非常小心名称间距,以便您的对象或函数不应该通过其他库替换.(如果对象或函数本身将被替换,您的整个常量将会去)



16> Andrew Hedge..:

有一段时间,我在传递给with()语句的对象文字中指定了"常量"(它实际上不是常量).我觉得它太聪明了.这是一个例子:

with ({
    MY_CONST : 'some really important value'
}) {
    alert(MY_CONST);
}

在过去,我还创建了一个CONST命名空间,我将放置所有常量.再次,与开销.啧.

现在,我只是尽var MY_CONST = 'whatever';到KISS.


如果这是一个比eval更邪恶的东西,它绝对是'与`.
eval非常邪恶!它烧毁了我的房子一次!

17> 小智..:

我的意见(仅适用于对象).

var constants = (function(){
  var a = 9;

  //GLOBAL CONSTANT (through "return")
  window.__defineGetter__("GCONST", function(){
    return a;
  });

  //LOCAL CONSTANT
  return {
    get CONST(){
      return a;
    }
  }
})();

constants.CONST = 8; //9
alert(constants.CONST); //9

尝试!但要明白 - 这是对象,但不是简单的变量.

也尝试一下:

const a = 9;



18> Steven Kapau..:

我也有这个问题.经过一段时间寻找答案并查看每个人的所有回复,我想我已经想出了一个可行的解决方案.

似乎我遇到的大部分答案都是使用函数来保存常量.正如许多论坛的许多用户所发布的那样,这些功能可以很容易地被客户端的用户覆盖.我对Keith Evetts的回答很感兴趣,即外部不能访问常量对象,而只能从内部的函数访问.

所以我提出了这个解决方案:

将所有内容放在匿名函数中,这样客户端就无法更改变量,对象等.还可以通过让其他函数从内部调用"真实"函数来隐藏"真实"函数.我还想过使用函数来检查客户端的用户是否更改了某个函数.如果功能已更改,请使用内部"受保护"的变量将其更改回来,并且无法更改.

/*Tested in: IE 9.0.8; Firefox 14.0.1; Chrome 20.0.1180.60 m; Not Tested in Safari*/

(function(){
  /*The two functions _define and _access are from Keith Evetts 2009 License: LGPL (SETCONST and CONST).
    They're the same just as he did them, the only things I changed are the variable names and the text
    of the error messages.
  */

  //object literal to hold the constants
  var j = {};

  /*Global function _define(String h, mixed m). I named it define to mimic the way PHP 'defines' constants.
    The argument 'h' is the name of the const and has to be a string, 'm' is the value of the const and has
    to exist. If there is already a property with the same name in the object holder, then we throw an error.
    If not, we add the property and set the value to it. This is a 'hidden' function and the user doesn't
    see any of your coding call this function. You call the _makeDef() in your code and that function calls
    this function.    -    You can change the error messages to whatever you want them to say.
  */
  self._define = function(h,m) {
      if (typeof h !== 'string') { throw new Error('I don\'t know what to do.'); }
      if (!m) { throw new Error('I don\'t know what to do.'); }
      else if ((h in j) ) { throw new Error('We have a problem!'); }
      else {
          j[h] = m;
          return true;
    }
  };

  /*Global function _makeDef(String t, mixed y). I named it makeDef because we 'make the define' with this
    function. The argument 't' is the name of the const and doesn't need to be all caps because I set it
    to upper case within the function, 'y' is the value of the value of the const and has to exist. I
    make different variables to make it harder for a user to figure out whats going on. We then call the
    _define function with the two new variables. You call this function in your code to set the constant.
    You can change the error message to whatever you want it to say.
  */
  self._makeDef = function(t, y) {
      if(!y) { throw new Error('I don\'t know what to do.'); return false; }
      q = t.toUpperCase();
      w = y;
      _define(q, w);
  };

  /*Global function _getDef(String s). I named it getDef because we 'get the define' with this function. The
    argument 's' is the name of the const and doesn't need to be all capse because I set it to upper case
    within the function. I make a different variable to make it harder for a user to figure out whats going
    on. The function returns the _access function call. I pass the new variable and the original string
    along to the _access function. I do this because if a user is trying to get the value of something, if
    there is an error the argument doesn't get displayed with upper case in the error message. You call this
    function in your code to get the constant.
  */
  self._getDef = function(s) {
      z = s.toUpperCase();
      return _access(z, s);
  };

  /*Global function _access(String g, String f). I named it access because we 'access' the constant through
    this function. The argument 'g' is the name of the const and its all upper case, 'f' is also the name
    of the const, but its the original string that was passed to the _getDef() function. If there is an
    error, the original string, 'f', is displayed. This makes it harder for a user to figure out how the
    constants are being stored. If there is a property with the same name in the object holder, we return
    the constant value. If not, we check if the 'f' variable exists, if not, set it to the value of 'g' and
    throw an error. This is a 'hidden' function and the user doesn't see any of your coding call this
    function. You call the _getDef() function in your code and that function calls this function.
    You can change the error messages to whatever you want them to say.
  */
  self._access = function(g, f) {
      if (typeof g !== 'string') { throw new Error('I don\'t know what to do.'); }
      if ( g in j ) { return j[g]; }
      else { if(!f) { f = g; } throw new Error('I don\'t know what to do. I have no idea what \''+f+'\' is.'); }
  };

  /*The four variables below are private and cannot be accessed from the outside script except for the
    functions inside this anonymous function. These variables are strings of the four above functions and
    will be used by the all-dreaded eval() function to set them back to their original if any of them should
    be changed by a user trying to hack your code.
  */
  var _define_func_string = "function(h,m) {"+"      if (typeof h !== 'string') { throw new Error('I don\\'t know what to do.'); }"+"      if (!m) { throw new Error('I don\\'t know what to do.'); }"+"      else if ((h in j) ) { throw new Error('We have a problem!'); }"+"      else {"+"          j[h] = m;"+"          return true;"+"    }"+"  }";
  var _makeDef_func_string = "function(t, y) {"+"      if(!y) { throw new Error('I don\\'t know what to do.'); return false; }"+"      q = t.toUpperCase();"+"      w = y;"+"      _define(q, w);"+"  }";
  var _getDef_func_string = "function(s) {"+"      z = s.toUpperCase();"+"      return _access(z, s);"+"  }";
  var _access_func_string = "function(g, f) {"+"      if (typeof g !== 'string') { throw new Error('I don\\'t know what to do.'); }"+"      if ( g in j ) { return j[g]; }"+"      else { if(!f) { f = g; } throw new Error('I don\\'t know what to do. I have no idea what \\''+f+'\\' is.'); }"+"  }";

  /*Global function _doFunctionCheck(String u). I named it doFunctionCheck because we're 'checking the functions'
    The argument 'u' is the name of any of the four above function names you want to check. This function will
    check if a specific line of code is inside a given function. If it is, then we do nothing, if not, then
    we use the eval() function to set the function back to its original coding using the function string
    variables above. This function will also throw an error depending upon the doError variable being set to true
    This is a 'hidden' function and the user doesn't see any of your coding call this function. You call the
    doCodeCheck() function and that function calls this function.    -    You can change the error messages to
    whatever you want them to say.
  */
  self._doFunctionCheck = function(u) {
      var errMsg = 'We have a BIG problem! You\'ve changed my code.';
      var doError = true;
      d = u;
      switch(d.toLowerCase())
      {
           case "_getdef":
               if(_getDef.toString().indexOf("z = s.toUpperCase();") != -1) { /*do nothing*/ }
               else { eval("_getDef = "+_getDef_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           case "_makedef":
               if(_makeDef.toString().indexOf("q = t.toUpperCase();") != -1) { /*do nothing*/ }
               else { eval("_makeDef = "+_makeDef_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           case "_define":
               if(_define.toString().indexOf("else if((h in j) ) {") != -1) { /*do nothing*/ }
               else { eval("_define = "+_define_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           case "_access":
               if(_access.toString().indexOf("else { if(!f) { f = g; }") != -1) { /*do nothing*/ }
               else { eval("_access = "+_access_func_string); if(doError === true) { throw new Error(errMsg); } }
               break;
           default:
                if(doError === true) { throw new Error('I don\'t know what to do.'); }
      }
  };

  /*Global function _doCodeCheck(String v). I named it doCodeCheck because we're 'doing a code check'. The argument
    'v' is the name of one of the first four functions in this script that you want to check. I make a different
    variable to make it harder for a user to figure out whats going on. You call this function in your code to check
    if any of the functions has been changed by the user.
  */
  self._doCodeCheck = function(v) {
      l = v;
      _doFunctionCheck(l);
  };
}())

似乎安全性确实是一个问题,并且无法从客户端"隐藏"您的编程.对我来说一个好主意是压缩你的代码,这样任何人,包括你,程序员,都很难阅读和理解它.您可以访问以下网站:http://javascriptcompressor.com/.(这不是我的网站,不要担心我不做广告.)这是一个允许您免费压缩和混淆Javascript代码的网站.

    复制上面脚本中的所有代码并将其粘贴到javascriptcompressor.com页面上的顶部textarea中.

    选中Base62编码复选框,选中Shrink Variables复选框.

    按"压缩"按钮.

    将其全部粘贴并保存在.js文件中,然后将其添加到页面顶部的页面中.



19> 小智..:

显然,这表明需要标准化的跨浏览器const关键字.

但现在:

var myconst = value;

要么

Object['myconst'] = value;

两者似乎都足够了,其他任何东西就像是用火箭筒射击飞行.

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有