为什么八进制数字字面量在严格模式下不被允许(以及有什么解决办法)?

30
为什么在JavaScript严格模式中不允许使用八进制数字字面量?这会带来什么危害?

"use strict";
var x = 010; //Uncaught SyntaxError: Octal literals are not allowed in strict mode.
<h1>Check browser console for errors</h1>

如果开发人员需要使用八进制(可能会误改数字的含义),是否有解决方法?


2
相关 - 提供了解决方法。但并未解释为什么不允许使用八进制字面量。 - James Thorpe
5
为什么很明显呢?这会让人们感到困惑,因为在日常生活中,给一个十进制数加前导零并不会改变它的值(例如从10变成08)。 - Martin Smith
1
这是另一个与八进制在语言中引起不一致性有关的问题,接受的答案还描述了为什么它们被移除。这里有一个问题 - James Thorpe
1
@学生,这不是什么大损失吧?除了Unix文件权限,我认为现在没有人使用八进制了。 - jcaron
2
@学生,这是唯一一个人们使用八进制的情况,因为由于3位分组(例如chmod 644 file),在那里使用八进制是有意义的。我很想看到过去10年中(甚至更久)是否存在其他普遍的用例。 - jcaron
显示剩余5条评论
7个回答

26

不允许使用八进制字面量,因为禁止它们会使程序员在脚本中使用前导零作为填充数不再流行。例如,请看以下代码片段:

var eight = 0008,
    nine = 00009,
    ten = 000010,
    eleven = 011;

console.log(eight, nine, ten, eleven);

看起来无害,对吧?我们这些有强迫症的程序员只是想把所有逗号对齐,使它看起来更漂亮。但问题在于:

8 9 8 9

这是输出结果。看看它变得多么不一致了?不是所有的以零填充的数字字面量都会转换为八进制,因为 8 和 9 不是八进制数字。当需要记住所有这些规则时,保持它们一致会更难,所以 严格模式 通过完全禁止此行为来使其更容易。

相反,您应该使用前导空格进行填充,或者如果想使用八进制,则利用带有可选的 radix 参数为 8parseInt() 方法来指定八进制。

以下分别是两种“解决方案”:

"use strict";

var eight  =  8,
    nine   =  9,
    ten    = 10,
    eleven = 11;

console.log(eight, nine, ten, eleven);

"use strict";

var eight  = parseInt('010', 8),
    nine   = parseInt('011', 8),
    ten    = parseInt('012', 8),
    eleven = parseInt('013', 8);

console.log(eight, nine, ten, eleven);


3
这是对于OP的“What is the harm?”问题最清晰的回答,也是为了对齐而进行填充的最佳解决方案。 - Velojet
我希望这不是真正的原因。归根结底,这并不重要,因为您可以完全抽象出语言并确保parseInt自己发生,但为什么不将001设置为语法错误,将01设置为有效的八进制字面量呢? - KernelDeimos
在严格模式下,任何带有前导零的多位整数都是语法错误。如果您想使用八进制,应该使用“0o”前缀。我不知道哪个规范引入了这种语法。 - Patrick Roberts

18
“为什么”这个问题实际上无法回答。关于“如何”,随便想一想...

"use strict";
var x = parseInt('010', 8);
document.write(x);


15

如今,由于大多数浏览器支持ES6,你可以这样编写代码:

const NINE = 0o11; // octal
const TEN = 0b1010; // binary
const SEVENTEEN = 0x11; // hexa

5
为什么JavaScript严格模式不允许八进制数字字面量?这会有什么危害?
在JS中,八进制历史上一直是标准的非标准扩展(在ES5中引入了严格模式,在附录B中,这是大多数实现支持的非标准特性集合:除此之外,它定义了与网站要求不兼容的八进制),而严格模式试图禁止所有非标准扩展。关于为什么它们从未被标准化的原因,我不知道。
如果开发人员需要使用八进制(可能会错误地改变数字的含义),是否有解决方法?
如@Amit所回答的,parseInt作为第二个参数为8的函数在严格模式下仍然有效。

4

基本上,当我在尝试在React中使用以下格式 date = new Date(2021,09,07) 并将其传递到另一个组件时,以便我可以转换为ISOString()或toLocaleString(),// {props.toISOString()}。 我遇到了这个错误“Legacy octal literals are not allowed in strict mode”。

但是,将月份和日期之前的“零”去掉后改为 date = new Date(2021,9,7) 对我来说完全正常地工作。


如果您有新的问题,请通过单击提问按钮来提出。如果它有助于提供上下文,请包含此问题的链接。- 来自审核 - Abilogos

-1
如果您正在对代码应用严格模式,则需要按照这种格式进行放置。
"use strict";
    var x = '010';
   console.log(x);

-4

可能您正在严格模式下的JS中,使用错误的字符串字面量(' ')来表示JSON。

正确的写法:{ "name": "Josh" }

错误的写法:{ 'name': 'Josh' }


1
我们可以在问题中看到代码和错误信息。没有JSON。也没有字符串(除了用于触发严格模式的字符串)。请查看被接受的2015年答案。 - Quentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接