ChatGPT解决这个技术问题 Extra ChatGPT

JavaScript中有常量吗?

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

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

Derek:你的 try/catch 不会限制你声明的 try/catch 块的范围吗?如果您没有正确确定范围,那么指定 constvar 有什么意义?
@Coderer 在当前的实现中,这将起作用,因为 constvar 具有相同的范围,这是函数级别,而不是块级别。如果您改为遵循即将推出的 ECMAScript 标准,则 constlet 具有相同的范围,这意味着它不起作用。
@Coderer 语言错误。 javascript中的变量是函数范围。这不是C。
@Jasper那很不幸。我怀疑他们是否真的破坏了所有使用 const 的现有代码。
不过老实说。为什么我们没有 const varconst let...

J
John Millikin

ES2015 开始,JavaScript 有了 const 的概念:

const MY_CONSTANT = "some-value";

这将在 pretty much all browsers except IE 8, 9 and 10 中起作用。有些可能还需要启用 strict mode

您可以将 var 与 ALL_CAPS 等约定一起使用,以表明如果您需要支持旧版浏览器或使用旧代码,则不应修改某些值:

var MY_CONSTANT = "some-value";

请注意,如果您不需要跨浏览器兼容性(或者您在 Rhino 或 Node.js 中进行服务器端编程),您可以使用 const 关键字。目前所有现代浏览器都支持它,除了 IE。
如今(3.5 年后),您可以使用 Object.defineProperty 创建也无法删除的只读属性。这适用于所有主要浏览器的当前版本(但 incorrectly in IE8)。查看@NotAName 的答案
由于这个答案在 2015 年仍然被谷歌排名靠前,应该说它现在已经过时了。 const 关键字现在正式成为该语言的一部分,并且受到所有浏览器的支持。根据 statcounter.com,只有百分之几的互联网用户仍在使用不支持 const 的旧浏览器版本。
B
Burke

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

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() 方法:(。

如果您不需要严格保护变量值,那么只需按照建议进行操作并使用全部大写的约定。


CONFIG.get = someNewFunctionThatBreaksTheCode...总而言之,您绝对不能在 JS 中强制使用常量(没有 const 关键字)。几乎你唯一能做的就是限制能见度。
我确实相信 private 是 JavaScript 中的未来保留字,如果我是你,我不会使用它。
B
Bill the Lizard

const 关键字在 the ECMAScript 6 draft 中,但到目前为止它只享有少量的浏览器支持:http://kangax.github.io/compat-table/es6/。语法是:

const CONSTANT_NAME = 0;

如果您尝试将值分配给 const,它不会引发任何错误。赋值失败了,常量仍然有它的原始值。恕我直言,这是一个主要的设计缺陷,但只要有一个清晰、一致的命名约定(例如流行的 ALL_CAPS),我认为它不会造成太大的痛苦。
s
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。如果您也想将 constants 引用设为只读,则可以 use const


应该提到这仅适用于 IE9+ kangax.github.io/compat-table/es5
C
C Nagle

IE 确实支持常量,例如:

<script language="VBScript">
 Const IE_CONST = True
</script>
<script type="text/javascript">
 if (typeof TEST_CONST == 'undefined') {
    const IE_CONST = false;
 }
 alert(IE_CONST);
</script>

男孩,谈论一些不是跨浏览器的东西。 . .对于跳出框框思考仍然+1。
VB脚本?那是什么? ;)
我通常对一般相关的跨浏览器问题投反对票,并给出特定于 IE 的答案。因为我讨厌那些认为 IE javascript 实现是“唯一”的人,而其他人只是被忽略。顺便说一句,谁在使用除 IE 之外的其他浏览器?
@Coluhuru 这个脚本似乎可以处理 IE 浏览器(使用 VBScript)和非 IE 浏览器(使用 JavaScript const)。你能解释一下它有什么问题吗?
我仍然很难接受可以更改常量。
s
sam

ECMAScript 5 确实引入了 Object.defineProperty

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

它是 supported in every modern browser(以及 IE ≥ 9)。

另请参阅:Object.defineProperty in ES5?


值得注意的是,这不像一个传统的常数。这只允许您定义一个常量属性(非常量对象的)。这也不会产生错误,甚至会返回您尝试设置的值。它根本不写值。
我最近读到,如果在 ECMAScript 5 的严格模式下解释执行分配的代码,则尝试使用 writable: false 分配给属性实际上会引发错误。将 'use strict' 写入代码的另一个原因。
您实际上可以省略 writable: false,因为那是 default
C
Community

不,一般不会。 Firefox 实现了 const,但我知道 IE 没有。

@John 指出了一种在其他语言中已使用多年的 const 的常见命名做法,我认为您没有理由不能使用它。当然,这并不意味着无论如何都不会有人改写变量的值。 :)


众所周知,如果IE不实现,还不如不存在。
不幸的是,实际上,这是真的。 IE 确实拥有巨大的市场份额。如果我拥有一家企业并在内部使用 Web 应用程序,我会在 FF 上进行标准化。我不知道为什么这么多人关心IE,它吹。
@Rich:谁说我的意见是事实?你做了相当的假设。此外,就我而言,IE 很糟糕的事实是事实。你可以有你自己的事实,我没说你必须相信我的。 :P 服用 Xanax 什么的...
@Rich B,是的,这只是一个愚蠢的评论,相信我,我会知道,我做了很多愚蠢的评论。 @Jason B. - 有趣的是,我昨晚遇到了这个问题.. const 在 FF 中工作,但不是 IE。感谢您的澄清
谁在乎IE?我不! FF 或 Chrome 或 Opera 等几乎可以安装在每个操作系统平台上。此外,计算机零售商通常知道旧版 IE 很糟糕,因此他们经常(甚至每次)在销售计算机之前安装替代浏览器。所以我决定让我开发的应用程序根本不关心不兼容的浏览器:如果浏览器开发人员关心尊重标准,他们的产品可以使用我的应用程序,否则,用户将使用不同的浏览器......我可以忍受它; -) 但是微软能失去部分市场吗?不,他们不能,所以“他们”会改变他们的开发政治!
M
MTS

在 JavaScript 中,我的偏好是使用函数来返回常量值。

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


alert(MY_CONSTANT());

值得指出的是,这属于@Burkes 回答(@trinithis 的评论)中提到的相同问题。 `MY_CONSTANT = function() { return "some-other-value"; } 打破它。 +1 不过,体面和快速的解决方案。
-1。这对 var SOME_NAME = value 没有任何好处(它仍然是可变的),是更多的代码,并且需要解释。
@PatrickM 虽然您确实可以在其他语言(例如 C 语言)中修改那种伪常量,但您不应该在这些语言上修改常量,但您仍然可以通过例如指针来完成。因此,只要您使用某种至少表明它是常数的方法,就可以了。
m
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。它是 absurd 的原因:

那么,IE9 对 const 做了什么?到目前为止,我们的决定是不支持它。它还不是一个共识功能,因为它从未在所有浏览器上可用。 ...最终,对于网络而言,最好的长期解决方案似乎是将其排除在外,然后等待标准化进程运行。

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

对于所有想法:每个功能都可以被覆盖(XSS 等)。所以 varfunction(){return} 没有区别。 const 是唯一的实常数。

更新:IE11 supports const

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


“它从未在所有浏览器上可用”。如果你不让它在 IE 中可用,那么它永远不会在所有浏览器中。
驾驶标准化并不适合所有人;)-公司来了又走了-感谢您引用木材中的可能性
还有一点:VBA 还不是所有浏览器中的共识功能,MS 支持 VBA 中的 const - 这是引导开发预算的掌握;)
h
hasen

如果您不介意使用函数:

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

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

a = constant(10);

a(); // 10

b = constant(20);

b(); // 20

我个人觉得这很令人愉快,特别是在从淘汰赛观察到习惯了这种模式之后。

*除非有人在你调用它之前重新定义了函数 constant


underscore.js 实现了一个与此代码相同的常量函数。
简单,简洁并回答了OP问题的精神。这应该得到更多的赞成票。
这对我来说从来没有真正起作用。即使闭包使其不可变,您分配给它的 var 仍然可以被覆盖。例如:a = constant(10); a(10); // 10 后跟 a = constant(25); a(); //25,没有给出错误或警告,没有迹象表明您的常量已被破坏。
如果我将值重新分配给 a,那么它会更改为新值
9
99 Problems - Syntax ain't one

使用“新”对象 api,您可以执行以下操作:

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

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

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

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

注意:赋值将在控制台中返回分配的值,但变量的值不会改变


在 safari 和 mozilla 中不起作用,如果您再次执行 define 语句 - 使用不同的值 - 它将重新分配值。
不是“不在 safari 中工作”,在 safari 中不受支持。不一样。如果您尝试这样做,它应该会抛出“未捕获的类型错误:无法重新定义属性:”。要么你做错了,要么你的 ff 实施不正确。我想这是两者的混合。
M
Manohar Reddy Poreddy

尽可能将常量分组到结构中:

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

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 采用具有“const”声明的新 ES6 标准。以上适用于早期的浏览器,如 IE8、IE9 和 IE10。


D
Derek 朕會功夫

忘记 IE 并使用 const 关键字。


为我工作!但后来我正在写一个 chrome 扩展,所以我知道我在一个理智的浏览器上......
@yoyo 关于编写扩展和插件的最佳部分——没有跨浏览器支持!
@Ian 欢迎来到 2019,跨浏览器的不一致性几乎消失了 :)
p
p.campbell

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

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

C
Community

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

但我会建议使用名称空间来区分其他变量。这会将其他变量的碰撞几率降至最低。

适当的命名空间,如

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') 获取值

** 在这两个示例中,您必须非常小心名称间距,以免您的对象或函数被其他库替换。(如果对象或函数本身将被替换,您的整个常量将消失)


A
Andrew Hedges

有一段时间,我在传递给 with() 语句的对象文字中指定了“常量”(实际上仍然不是常量)。我以为它很聪明。这是一个例子:

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

过去,我还创建了一个 CONST 命名空间,用于放置我的所有常量。再次,与开销。嘘。

现在,我只需执行 var MY_CONST = 'whatever';KISS


如果有比 eval 更邪恶的东西,那肯定是 with
eval 很邪恶!它曾经把我的房子烧了!
A
Alessandro Minoccheri

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

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;

S
Steven Kapaun

我也有这个问题。在寻找答案并查看每个人的所有回复之后,我想我已经想出了一个可行的解决方案。

似乎我遇到的大多数答案都是使用函数来保存常量。正如许多论坛的许多用户所发布的那样,客户端的用户可以轻松地覆盖这些功能。我对 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 页面的顶部文本区域中。选中 Base62 编码复选框,选中 Shrink Variables 复选框。按压缩按钮。将其全部粘贴并保存在 .js 文件中,然后将其添加到页面头部的页面中。


这是一个很好的解决方案,可以很好地包装为要包含的库。但我不喜欢这段代码中变量的命名。为什么要删除 Keith 代码中使用的“名称”和“值”等描述性名称?小问题,但仍然。
D
Devin Burke

很明显,这表明需要一个标准化的跨浏览器 const 关键字。

但现在:

var myconst = value;

或者

Object['myconst'] = value;

两者似乎都足够了,其他任何事情都像是用火箭筒射击苍蝇。


采用旧的 var myconst = value;并且为了调试使用额外的调试代码...... - 只要不是所有浏览器都支持 const 就可以疯狂地工作
P
PhiLho

我在 Greasemonkey 脚本中使用 const 而不是 var,但这是因为它们只能在 Firefox 上运行...
名称约定也确实是可行的方法(我两者都做!)。


R
Rene Saarsoo

在 JavaScript 中,我的做法是尽可能避免使用常量,而是使用字符串。当您想将常量暴露给外界时,会出现常量问题:

例如,可以实现以下 Date API:

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

但是简单地写成更短更自然:

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

这样,“天”和“小时”实际上就像常量一样,因为您无法从外部更改“小时”代表多少秒。但是很容易覆盖 MyModule.Date.HOUR

这种方法也有助于调试。如果 Firebug 告诉您 action === 18,很难理解它的含义,但是当您看到 action === "save" 时,它就会立即清楚。


不幸的是,很容易出现拼写错误 - 例如 "Hours" 而不是 "hours" - 但 IDE 可能会提前让您知道 Date.Hours 未定义。
W
Webveloper

好吧,这很难看,但它在 Firefox 和 Chromium 中给了我一个常量,在 Safari 和 Opera 中给了我一个不定常量(WTF?),在 IE 中给了我一个变量。

当然 eval() 是邪恶的,但没有它,IE 会抛出错误,阻止脚本运行。

Safari 和 Opera 支持 const 关键字,但您可以更改 const 的值。

在此示例中,服务器端代码将 JavaScript 写入页面,将 {0} 替换为一个值。

try{
    // i can haz const?
    eval("const FOO='{0}';");
    // for reals?
    var original=FOO;
    try{
        FOO='?NO!';
    }catch(err1){
        // no err from Firefox/Chrome - fails silently
        alert('err1 '+err1);
    }
    alert('const '+FOO);
    if(FOO=='?NO!'){
        // changed in Sf/Op - set back to original value
        FOO=original;
    }
}catch(err2){
    // IE fail
    alert('err2 '+err2);
    // set var (no var keyword - Chrome/Firefox complain about redefining const)
    FOO='{0}';
    alert('var '+FOO);
}
alert('FOO '+FOO);

这有什么好处?不多,因为它不是跨浏览器。充其量,至少有些浏览器不会让小书签或第三方脚本修改该值,这可能会让您放心。

使用 Firefox 2、3、3.6、4、Iron 8、Chrome 10、12、Opera 11、Safari 5、IE 6、9 测试。


喜欢那个代码!丑陋到极点,但是对 const 支持的一个很好的测试。 =)
有点好笑,嗯——你可以输入多少行来声明一个常量?
M
Muhammad Reda

如果值得一提,您可以使用 $provide.constant()angular 中定义常量

angularApp.constant('YOUR_CONSTANT', 'value');

...您可以在 VBA 中使用 const ... xbrowser?... ups ... ;)
OP 询问有关 javascript 的问题,回答涉及特定的严重固执己见的 JS 框架。几乎跑题了。
@rounce:​​​​​​​​​​​​​​​​​​​​​题外答案仍然是答案,不要将它们标记不是答案而是downvotevote to delete 代替。请参阅How do I properly use the “Not an Answer” flag?
@KevinGuan 指出,将来会这样做。
C
Community

Burke's answer 的改进版本,您可以使用 CONFIG.MY_CONST 而不是 CONFIG.get('MY_CONST')

它需要 IE9+ 或真正的网络浏览器。

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

    var result = {};
    for (var n in constants)
        if (constants.hasOwnProperty(n))
            Object.defineProperty(result, n, { value: constants[n] });

    return result;
}());

* 属性是只读的,仅当初始值不可变时。


l
le_m

JavaScript ES6(重新)引入了 all major browsers 中支持的 const keyword

通过 const 声明的变量不能重新声明或重新分配。

除此之外,const 的行为类似于 let

对于原始数据类型(Boolean、Null、Undefined、Number、String、Symbol),它的行为与预期的一样:

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

注意:注意关于对象的陷阱:

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

如果您确实需要一个不可变且绝对恒定的对象:只需使用 const ALL_CAPS 来明确您的意图。无论如何,对所有 const 声明都遵循一个很好的约定,因此请依赖它。


仅从 IE11 :-(
r
rounce

另一种选择是:

var constants = {
      MY_CONSTANT : "myconstant",
      SOMETHING_ELSE : 123
    }
  , constantMap = new function ConstantMap() {};

for(var c in constants) {
  !function(cKey) {
    Object.defineProperty(constantMap, cKey, {
      enumerable : true,
      get : function(name) { return constants[cKey]; }
    })
  }(c);
}

然后简单地说:var foo = constantMap.MY_CONSTANT

如果您要使用 constantMap.MY_CONSTANT = "bar",它将没有任何效果,因为我们正在尝试将赋值运算符与 getter 一起使用,因此 constantMap.MY_CONSTANT === "myconstant" 将保持为真。


E
Erik Lucio

在 Javascript 中已经存在 constants。你定义一个像这样的常量:

const name1 = value;

这不能通过重新分配来改变。


根据答案中的链接,这是一项实验性功能,应谨慎使用。
当然,我同意你的看法。但是在最新版本的浏览器中它可以工作。
R
Ritumoni Sharma

关键字 'const' 是较早提出的,现在它已正式包含在 ES6 中。通过使用 const 关键字,您可以传递将充当不可变字符串的值/字符串。


B
Bill the Lizard

在 JavaScript 中引入常量充其量只是一种 hack。

在 JavaScript 中创建持久且全局可访问的值的一种好方法是声明一个具有一些“只读”属性的对象字面量,如下所示:

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

您会将所有常量组合在一个“我的”附件对象中,您可以在其中查找存储的值或您可能决定为此放置的任何其他内容。现在让我们测试它是否有效:

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

正如我们所见,“my.constant1”属性保留了它的原始值。您已经为自己制作了一些不错的“绿色”临时常量...

但当然,这只会防止您意外修改、更改、取消或清空您的属性常量值,如给定示例中的直接访问。

否则我仍然认为常量是假人。而且我仍然认为,用你的巨大自由来换取一个具有欺骗性的安全的小角落是最糟糕的交易。


i
isomorphismes

除了上面提到的之外,Rhino.js 还实现了 const