字符串中的空字符

24

考虑以下字符串:

var s = "A\0Z";

它的长度是3,由 s.length 给出。使用 console.log 您可以看到字符串没有被截断以及 s[1]""s.charCodeAt(1)0

在 Firefox 中弹出时,你会看到 AZ。在 Chrome/Linux 上使用 alert(s) 时,\0 终止了字符串,你会看到 A

我的问题是:浏览器和 Javascript 引擎应该做什么?这里的 Chrome 有 bug 吗?是否有定义应该发生什么的文档?

由于这是关于标准的问题,需要提供参考资料。


1
在 Chrome 23 控制台中,我看到 AB - James Allardice
2
当然可以,只要遵循标准。\0不是一个被认可的转义字符 :) - Gung Foo
在Chrome中,alert('A\0Z')现在显示为'AZ'。问题已经修复。 :) - broofa
@broofa 在Ubuntu上,Chrome或Chromium(28.0.1500.71-0ubuntu1.12.04.1)上并没有固定。 - Denys Séguret
同样适用于Chrome 44 Ubuntu。 - Denys Séguret
显示剩余8条评论
3个回答

21
浏览器应该将字符串及其长度分开跟踪,因为标准中没有空终止符。(字符串只是一个带有长度的对象)。
Chrome似乎使用标准C字符串函数,在\0处终止。回答你的问题之一:对我来说,这构成了Chrome处理alert()函数的错误。
正式规范如下:
字符串文字是用单引号或双引号括起来的零个或多个字符。每个字符都可以由转义序列表示。除了闭合引号字符、反斜杠、回车符、行分隔符、段落分隔符和换行符外,所有字符都可以在字符串文字中直接出现。任何字符都可以以转义序列的形式出现。
另外:
字符串字面值代表String类型的值。字面值的String值(SV)是根据字符串字面值的各个部分贡献的字符值(CV)来描述的。
关于NUL字节:
EscapeSequence :: 0的CV [Character Value]为 <NUL>字符(Unicode值为0000),其中lookahead ∉ DecimalDigit。
因此,NUL字节应该只是“另一个字符值”,没有特殊含义,与其他语言不同,在其他语言中它可能会结束SV(字符串值)。
有关(有效的)“String Single Character Escape Sequences”的参考,请查看ECMAScript Language spec section 7.8.4。在段落末尾有一个表格列出了上述转义序列。
对于想编写Javascript引擎的人可能需要学到的内容是:不要使用C / C ++字符串函数。 :)

你读完整个部分了吗?看起来你只读了“注意”部分...它包含了“如果i为零,则返回由<NUL>字符(Unicode值0000)组成的EscapeValue。”和“\ 0表示<NUL>字符,不能后跟十进制数字。”,更不用说其他有关转义的一般信息了... - Ian
OT:你是否已经向Chromium或V8报告了这个bug?我很想看看它 :) - Alvin Wong
4
@AlvinWong,我进入了问题164126 - Denys Séguret
'\000\0\u0000\x00' === '\0\0\0\0' 的意思是相等。 - iegik
@DenysSéguret - 我已确认该问题仍存在于 Chrome 47 中。我已在你提供的 Google 问题链接上添加了评论。 - JDB
显示剩余8条评论

8

Javascript把null字符视为任何其他字符,你的问题是如何在控制台或警报中显示它,在不同的浏览器中可能会有所不同,没有关于此的标准,所以在谷歌浏览器中是可以的。


3
我不明白为什么这个回答被踩了。虽然简短,但在 Nelson 回复之前它是最正确的答案,而 Nelson 的回复则更详细地表述了相同的内容。 - Jukka K. Korpela

3
你询问的是alert()方法在不同浏览器中表现不一致的行为,因此与Script对象和ECMAscript规范无关,而是与alert()如何显示String对象有关。 alert()是Window对象的一个方法,ECMAscript没有定义它(只告诉宿主环境可以提供全局对象作为window对象)。
但偶然间发现了一个w3c规范定义alert()的行为,不幸的是,它非常缺乏,并没有提供任何关于如何显示带有嵌入空字符的消息的提示。
因此,就像规范中未指定的任何其他细节一样,这种行为留给浏览器自己实现。

1
假设已经定义了字符串字面量中的NUL字符应该如何处理,重新定义不是多余的吗? - Gung Foo
3
所引用的"w3c规范"本身说:“这是一份草案文件,可能随时被其他文件更新、替换或废弃。引用此文档时,将其视为正在进行的工作是不恰当的。” 此外,它仅说明了alert()方法应该“向用户显示给定的消息”,但没有指定其中控制字符如何解释。因此,在NUL处停止,虽然质量很差,但并不违反任何规范。 - Jukka K. Korpela

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