在JavaScript中,"\n"被视为字符串文字。

4

我有一个带有值为“\n”的选项标签的选择标签。当选择该选项并使用jQuery获取值时,JavaScript似乎将其视为字符串文字而不是解释为换行符。

我尝试了转义、取消转义、先转义再取消转义、使用jQuery htmlEncoding技术、jQuery htmlDecoding技术,甚至尝试与空字符串连接。我快要抓狂了。这应该很简单。

至少有5种解决方法立即在我的脑海中浮现,具有不同程度的优雅,但此时此刻,我更想知道为什么会出现这种行为。是否有一些简单的东西我错过了?我的真正问题是“为什么JavaScript在一个上下文中以某种方式处理字符串\n,在另一个上下文中则不同”,而不是“我该如何让它工作”。

以下是代码:

Html

<select id="delimiter">
  <option value="\n">New Line</option> <!--This should produce a linefeed-->
  <option value=",">, (Comma)</option>
  <option value=";">; (Semicolon)</option>
  <option value="\t">Tab</option>
</select>
<button  onclick="doit()">
  Check It
</button>

JavaScript

function doit(){
  var delimiter = $("#delimiter").val();

  console.debug("\n"); //produces an actual linefeed character
  console.debug(delimiter); //this produces the string "\n"
}

我有一个相关的 Codepen,链接在这里:https://codepen.io/codysechelski/pen/MoJKMB?editors=1111

2
HTML没有像\n\t这样的转义序列。https://codepen.io/tarabyte/pen/RgKZwd?editors=1111,所以并不是`JavaScript`在执行此操作 :) - Yury Tarabanko
但是一旦我们在JavaScript中获取了选项的值,它只是一个字符串,对吧?我认为它应该与var s = '\n'相同。但实际似乎不是这样的情况。 - Cody
是的,长度为2的字符串由两个字符\n组成,翻译成字符串文字应该是'\\n'。尝试使用console.debug(delimiter.split(''), delimiter === '\\n') - Yury Tarabanko
谢谢,那个解释正是我怀疑的,但是var s = "/n"有什么神奇之处呢?对我来说,它看起来像一个包含两个字符的字符串。然而,它产生了一个单一的换行符。我并不想刁难,我只是真的想了解JS在幕后做了什么。$("#delimiter").val()是否会产生与var s = '\n'不同的字符串?此外,有没有办法将当前返回和翻译为“//n”的字符串转换为换行符? - Cody
3个回答

4

将您的值中的"\n"替换为新行代码:"&#13;" 在HTML标签属性中,必须使用HTML字符实体来表示特殊字符。


谢谢,那确实解决了问题,但它并没有真正给我一个解释。我更关心的是为什么JavaScript在一个上下文中以一种方式处理\n字符串,而在另一个上下文中则不同。 - Cody

4
为什么JavaScript在不同的上下文中对一个换行符\n的处理方式不同?
首先,你需要理解字符串字面量并不是内存中实际的字符串,而是js语法用于创建字符串的一部分。因此,以“\”字符开头的转义序列会让js引擎以不同的方式处理接下来的字符。
HTML没有这种特殊的语法,所以"\\"就是"\","\n"就是"\n"。当这个字符串通过DOM API(不是js语法的一部分)跨越html-js边界时,它仍然是相同的两个字母的字符串。
顺便说一下,在js中有多种编码换行的方式,都会在内存中生成相同的字符串。

const withEscSequence = '\n'

// es2015
const usingStringTemplate = `
`
// directly from char code
const fromCharCode = String.fromCharCode(10)

// using unicode escape sequence
const unicodeEscSequence = '\u000A'

// using hex escape sequence
const hexEscSequence = '\x0A'


console.log(withEscSequence === usingStringTemplate, withEscSequence === fromCharCode, withEscSequence === unicodeEscSequence, withEscSequence ===  hexEscSequence)


谢谢您详细的回答。我现在明白了! :) - Cody

2
为什么JavaScript在一个上下文中将\n字符串一种方式处理,但在另一个上下文中却不同呢?
因为它不是JavaScript,也不是字符串文字。 <option value="\n"> 是普通的HTML,反斜杠在HTML中不是转义字符。您可以使用字面换行符或字符实体
我尝试过转义...
但显然不是正确的方法。它总是取决于使用哪种转义字符,并且有时甚至需要链接它们。一些适当的解决方案:
  • Literal characters in the HTML source:

    <option value="
    ">New Line</option>
    <option value=",">Comma</option>
    <option value=" ">Tab</option>
    

    selectEl.value
    
  • Character entity references in the HTML source, to avoid the weird formatting:

    <option value="&#x000A;">New Line</option> <!-- or &#10; -->
    <option value=",">Comma</option>
    <option value="&#x0009;">Tab</option> <!-- or &#9; -->
    

    selectEl.value
    
  • JSON literals in the HTML source to avoid knowing charcodes:

    <option value="&quot;\n&quot;">New Line</option>
    <option value="&quot;,&quot;">Comma</option>
    <option value="&quot;\t&quot;">Tab</option>
    

    JSON.parse(selectEl.value)
    
  • JSON string contents in the HTML source:

    <option value="\n">New Line</option>
    <option value=",">Comma</option>
    <option value="\t">Tab</option>
    

    JSON.parse('"'+selectEl.value+'"')
    

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