JavaScript 中有常量吗?
有没有办法在 JavaScript 中使用常量?
如果不是,指定用作常量的变量的常见做法是什么?
Is there a way to use constants in JavaScript?
If not, what's the common practice for specifying variables that are used as constants?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
从 ES2015 开始,JavaScript 就有了
const
:这将在 < a href="https://caniuse.com/#search=const" rel="noreferrer">几乎所有浏览器(IE 8、9 和 10 除外)。 有些可能还需要启用严格模式。
您可以将
var
与 ALL_CAPS 等约定一起使用,以表明如果您需要支持较旧的浏览器或正在使用旧代码,则不应修改某些值:Since ES2015, JavaScript has a notion of
const
:This will work in pretty much all browsers except IE 8, 9 and 10. Some may also need strict mode enabled.
You can use
var
with conventions like ALL_CAPS to show that certain values should not be modified if you need to support older browsers or are working with legacy code:您是否试图保护变量不被修改? 如果是这样,那么您可以使用模块模式:
使用这种方法,无法修改值。 但是,您必须在 CONFIG 上使用 get() 方法:(。
如果您不需要严格保护变量值,那么只需按照建议进行操作并使用全部大写的约定。
Are you trying to protect the variables against modification? If so, then you can use a module pattern:
Using this approach, the values cannot be modified. But, you have to use the get() method on CONFIG :(.
If you don't need to strictly protect the variables value, then just do as suggested and use a convention of ALL CAPS.
const
关键字位于ECMAScript 6 草案 但截至 2015 年 8 月 8 日,它只获得了少量浏览器支持。 对于当前状态,请考虑此 ES6 兼容性表。 语法是:The
const
keyword is in the ECMAScript 6 draft but as of Aug 8, 2015 it had only enjoyed a smattering of browser support. For the current state, consider this ES6 compatibility table. The syntax is:请参阅 Object.freeze。 如果您想使用
常量
引用,可以使用const
也是只读的。See Object.freeze. You can use
const
if you want to make theconstants
reference read-only as well.IE 确实支持常量,例如:
IE does support constants, sort of, e.g.:
ECMAScript 5 确实引入了
Object.defineProperty
:所有现代浏览器都支持(以及 IE ≥ 9)。
另请参阅:ES5 中的 Object.defineProperty?
ECMAScript 5 does introduce
Object.defineProperty
:It's supported in every modern browser (as well as IE ≥ 9).
See also: Object.defineProperty in ES5?
不,一般来说不是。 Firefox 实现了
const
但我知道 IE 没有。@John 指出了常量的常见命名实践,该实践已在其他语言中使用多年,我认为你没有理由不能使用它。 当然,这并不意味着有人不会重写变量的值。 :)
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. :)
在 JavaScript 中,我更喜欢使用函数返回常量值。
In JavaScript, my preference is to use functions to return constant values.
Mozillas MDN Web 文档 包含很好的示例和关于
const
的解释。 摘录:但遗憾的是 IE9/10 仍然不支持
const
。 原因是 荒谬:他们不实现它是因为其他浏览器没有正确实现它?! 太害怕让它变得更好? 无论是否标准定义,常量就是常量:设置一次,永不更改。
对于所有的想法:每个函数都可以被覆盖(XSS 等)。 所以
var
或function(){return}
没有区别。const
是唯一的实常量。更新:
IE11 支持
const
:Mozillas MDN Web Docs contain good examples and explanations about
const
. Excerpt:But it is sad that IE9/10 still does not support
const
. And the reason it's absurd: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
orfunction(){return}
.const
is the only real constant.Update:
IE11 supports
const
:如果您不介意使用函数:
这种方法为您提供函数而不是常规变量,但它保证*一旦设置值,任何人都无法更改它。
我个人觉得这相当令人愉快,特别是在习惯了淘汰赛可观察到的这种模式之后。
*除非有人在你调用函数之前重新定义了该函数
constant
If you don't mind using functions:
This approach gives you functions instead of regular variables, but it guarantees* that no one can alter the value once it's set.
I personally find this rather pleasant, specially after having gotten used to this pattern from knockout observables.
*Unless someone redefined the function
constant
before you called it使用“新”对象 api,您可以执行以下操作:
查看 请访问 Mozilla MDN 了解更多详情。 它不是第一级变量,因为它附加到一个对象,但如果你有一个范围,任何东西,你可以将它附加到它。
this
应该也能工作。因此,例如在全局范围内执行此操作将在窗口上声明一个伪常量值(这是一个非常糟糕的主意,您不应该粗心地声明全局变量)
注意:赋值将在控制台中返回给您分配的值,但是变量的值不会改变
with the "new" Object api you can do something like this:
take a look at this on the Mozilla MDN for more specifics. It's not a first level variable, as it is attached to an object, but if you have a scope, anything, you can attach it to that.
this
should work as well.So for example doing this in the global scope will declare a pseudo constant value on the window (which is a really bad idea, you shouldn't declare global vars carelessly)
note: assignment will give you back the assigned value in the console, but the variable's value will not change
忘记 IE 并使用
const
关键字。Forget IE and use the
const
keyword.尽可能将常量分组到结构中:
例如,在我当前的游戏项目中,我使用了以下内容:
分配:
比较:
最近我正在使用,用于比较:
IE11 使用具有“const”声明的新 ES6 标准。
以上适用于 IE8、IE9 等早期浏览器。 IE10。
Group constants into structures where possible:
Example, in my current game project, I have used below:
Assignment:
Comparision:
More recently I am using, for comparision:
IE11 is with new ES6 standard that has 'const' declaration.
Above works in earlier browsers like IE8, IE9 & IE10.
您可以轻松地为脚本配备可设置但不可更改的常量机制。 尝试更改它们将产生错误。
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.
然而,没有确切的跨浏览器预定义方法来做到这一点,您可以通过控制变量的范围来实现它,如其他答案所示。
但我建议使用名称空间来区别于其他变量。 这会将其他变量发生碰撞的可能性降到最低。
使用它时,正确的命名空间
是
iw_constant.name
或iw_constant.age
您还可以使用 Object.freeze 方法阻止添加任何新键或更改 iw_constant 内的任何键。 但是,旧版浏览器不支持它。
例如:
对于较旧的浏览器,您可以使用 polyfill 进行冻结方法。
如果您可以调用函数,那么以下是定义常量的最佳跨浏览器方法。 在自执行函数中确定对象的作用域并为常量返回 get 函数
ex:
//获取值使用
iw_constant('name')
或iw_constant('age')
** 在这两个示例中,您必须非常小心名称间距,以便您的对象或函数不应该通过其他库替换。(如果对象或函数本身将被替换,您的整个常量将消失)
Yet there is no exact cross browser predefined way to do it , you can achieve it by controlling the scope of variables as showed on other answers.
But i will suggest to use name space to distinguish from other variables. this will reduce the chance of collision to minimum from other variables.
Proper namespacing like
so while using it will be
iw_constant.name
oriw_constant.age
You can also block adding any new key or changing any key inside iw_constant using Object.freeze method. However its not supported on legacy browser.
ex:
For older browser you can use polyfill for freeze method.
If you are ok with calling function following is best cross browser way to define constant. Scoping your object within a self executing function and returning a get function for your constants
ex:
//to get the value use
iw_constant('name')
oriw_constant('age')
** In both example you have to be very careful on name spacing so that your object or function shouldn't be replaced through other library.(If object or function itself wil be replaced your whole constant will go)
有一段时间,我在传递给
with()
语句的对象文字中指定了“常量”(实际上仍然不是常量)。 我觉得这真是太聪明了。 这是一个示例:过去,我还创建了一个
CONST
命名空间,在其中放置所有常量。 再次,与开销。 谢什。现在,我只需执行
var MY_CONST = 'whatever';
即可 KISS 。For a while, I specified "constants" (which still weren't actually constants) in object literals passed through to
with()
statements. I thought it was so clever. Here's an example:In the past, I also have created a
CONST
namespace where I would put all of my constants. Again, with the overhead. Sheesh.Now, I just do
var MY_CONST = 'whatever';
to KISS.我的意见(仅适用于对象)。
尝试! 但要明白 - 这是对象,但不是简单的变量。
也尝试一下:
My opinion (works only with objects).
Try! But understand - this is object, but not simple variable.
Try also just:
我也遇到过这个问题。 经过很长一段时间寻找答案并查看每个人的所有回应后,我想我已经找到了一个可行的解决方案。
看来我遇到的大多数答案都是使用函数来保存常量。 正如许多论坛的许多用户所发表的那样,客户端的用户可以轻松地重写这些函数。 我对 Keith Evetts 的回答很感兴趣,即外部不能访问常量对象,只能从内部函数访问。
所以我想出了这个解决方案:
将所有内容放在匿名函数中,这样客户端就无法更改变量、对象等。 还可以通过让其他函数从内部调用“真实”函数来隐藏“真实”函数。 我还考虑使用函数来检查客户端的用户是否更改了函数。 如果功能已更改,请使用内部“受保护”且无法更改的变量将其更改回来。
看来安全确实是一个问题,并且没有办法从客户端“隐藏”您的编程。 对我来说,一个好主意是压缩你的代码,这样任何人(包括你,程序员)都很难阅读和理解它。 您可以访问以下网站:http://javascriptcompressor.com/。 (这不是我的网站,别担心,我不是在做广告。)这是一个可以让您免费压缩和混淆 Javascript 代码的网站。
I too have had a problem with this. And after quite a while searching for the answer and looking at all the responses by everybody, I think I've come up with a viable solution to this.
It seems that most of the answers that I've come across is using functions to hold the constants. As many of the users of the MANY forums post about, the functions can be easily over written by users on the client side. I was intrigued by Keith Evetts' answer that the constants object can not be accessed by the outside, but only from the functions on the inside.
So I came up with this solution:
Put everything inside an anonymous function so that way, the variables, objects, etc. cannot be changed by the client side. Also hide the 'real' functions by having other functions call the 'real' functions from the inside. I also thought of using functions to check if a function has been changed by a user on the client side. If the functions have been changed, change them back using variables that are 'protected' on the inside and cannot be changed.
It also seems that security is really a problem and there is not way to 'hide' you programming from the client side. A good idea for me is to compress your code so that it is really hard for anyone, including you, the programmer, to read and understand it. There is a site you can go to: http://javascriptcompressor.com/. (This is not my site, don't worry I'm not advertising.) This is a site that will let you compress and obfuscate Javascript code for free.
显然,这表明需要标准化的跨浏览器 const 关键字。
但就目前而言:
或者
两者似乎都足够了,其他任何事情都就像用火箭筒射苍蝇一样。
Clearly this shows the need for a standardized cross-browser const keyword.
But for now:
or
Both seem sufficient and anything else is like shooting a fly with a bazooka.
我在 Greasemonkey 脚本中使用
const
而不是var
,但这是因为它们只能在 Firefox 上运行...名称约定确实也是一种可行的方法(我两者都做!)。
I use
const
instead ofvar
in my Greasemonkey scripts, but it is because they will run only on Firefox...Name convention can be indeed the way to go, too (I do both!).
在 JavaScript 中,我的做法是尽可能避免使用常量,而使用字符串。 当您想要将常量公开给外界时,常量的问题就会出现:
例如,可以实现以下日期 API:
但简单地编写会更短、更自然:
这样“天”和“小时”实际上就像常量一样,因为您无法从外部更改“小时”代表的秒数。 但很容易覆盖
MyModule.Date.HOUR
。这种方法也有助于调试。 如果 Firebug 告诉您
action === 18
,则很难弄清楚它的含义,但是当您看到action === "save"
时,它就立即清楚了。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:
But it's much shorter and more natural to simply write:
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 seeaction === "save"
then it's immediately clear.好吧,这很难看,但它在 Firefox 和 Chromium 中给了我一个常量,在 Safari 和 Opera 中给了一个不恒定的常量(WTF?),在 IE 中给了一个变量。
当然 eval() 是邪恶的,但如果没有它,IE 就会抛出错误,从而阻止脚本运行。
Safari 和 Opera 支持 const 关键字,但您可以更改 const 的值。
在此示例中,服务器端代码将 JavaScript 写入页面,并将 {0} 替换为值。
这有什么用? 不多,因为它不是跨浏览器的。 充其量,也许可以让您安心一点,至少某些浏览器不会让书签或第三方脚本修改该值。
使用 Firefox 2、3、3.6、4、Iron 8、Chrome 10、12、Opera 11、Safari 5、IE 6、9 进行测试。
Okay, this is ugly, but it gives me a constant in Firefox and Chromium, an inconstant constant (WTF?) in Safari and Opera, and a variable in IE.
Of course eval() is evil, but without it, IE throws an error, preventing scripts from running.
Safari and Opera support the const keyword, but you can change the const's value.
In this example, server-side code is writing JavaScript to the page, replacing {0} with a value.
What is this good for? Not much, since it's not cross-browser. At best, maybe a little peace of mind that at least some browsers won't let bookmarklets or third-party script modify the value.
Tested with Firefox 2, 3, 3.6, 4, Iron 8, Chrome 10, 12, Opera 11, Safari 5, IE 6, 9.
如果值得一提,您可以使用 Angular 定义常量。 org/api/auto/service/$provide#constant" rel="nofollow">
$provide.constant()
If it is worth mentioning, you can define constants in angular using
$provide.constant()
Burke 的答案的改进版本,可让您执行
CONFIG.MY_CONST
而不是CONFIG .get('MY_CONST')
。它需要 IE9+ 或真正的网络浏览器。
* 仅当初始值不可变时,属性才是只读的。
An improved version of Burke's answer that lets you do
CONFIG.MY_CONST
instead ofCONFIG.get('MY_CONST')
.It requires IE9+ or a real web browser.
* The properties are read-only, only if the initial values are immutable.
JavaScript ES6(重新)引入了
const
关键字,所有主流浏览器均支持该关键字。除此之外,
const
的行为类似于让
。它的行为与原始数据类型(布尔、空、未定义、数字、字符串、符号)的预期相同:
注意:请注意有关对象的陷阱:
如果您确实需要一个不可变且绝对恒定的对象:只需使用
const ALL_CAPS
来明确您的意图。 无论如何,对于所有const
声明来说,这是一个很好的约定,因此只需依赖它即可。JavaScript ES6 (re-)introduced the
const
keyword which is supported in all major browsers.Apart from that,
const
behaves similar tolet
.It behaves as expected for primitive datatypes (Boolean, Null, Undefined, Number, String, Symbol):
Attention: Be aware of the pitfalls regarding objects:
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 allconst
declarations anyway, so just rely on it.另一种选择是这样的:
然后简单地:
var foo = ConstantMap.MY_CONSTANT
如果你要
constantMap.MY_CONSTANT = "bar"
它不会有任何效果,因为我们正在尝试将赋值运算符与 getter 结合使用,因此constantMap.MY_CONSTANT === "myconstant"
将保持 true。Another alternative is something like:
Then simply:
var foo = constantMap.MY_CONSTANT
If you were to
constantMap.MY_CONSTANT = "bar"
it would have no effect as we're trying to use an assignment operator with a getter, henceconstantMap.MY_CONSTANT === "myconstant"
would remain true.Javascript 中已经存在常量。 您可以这样定义一个常量:
这不能通过重新分配来更改。
in Javascript already exists constants. You define a constant like this:
This cannot change through reassignment.
关键字const是较早提出的,现在已经正式包含在ES6中。 通过使用 const 关键字,您可以传递一个充当不可变字符串的值/字符串。
The keyword 'const' was proposed earlier and now it has been officially included in ES6. By using the const keyword, you can pass a value/string that will act as an immutable string.
将常量引入 JavaScript 充其量只是一种 hack。
在 JavaScript 中创建持久且全局可访问的值的一种好方法是声明一个带有一些“只读”属性的对象文字,如下所示:
您将把所有常量分组在一个“我的”附件对象中,您可以在其中查找您的存储值或您可能决定放在那里的任何其他内容。 现在让我们测试一下它是否有效:
正如我们所看到的,“my.constant1”属性保留了其原始值。 您已经为自己创建了一些漂亮的“绿色”临时常量...
但是,当然,这只能防止您通过直接访问(如给定示例中所示)意外修改、更改、无效或清空属性常量值。
否则我仍然认为常量是给傻瓜用的。
我仍然认为,用你的巨大自由来换取一小部分欺骗性的安全是最糟糕的交易。
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:
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:
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.
除了上面提到的之外,
Rhino.js
还实现了const
。Rhino.js
implementsconst
in addition to what was mentioned above.