31

String.rawECMAScript 6 中引入的 Raw String Access 的实际用途是什么?

// String.raw(callSite, ...substitutions)

function quux (strings, ...values) {
    strings[0] === "foo\n"
    strings[1] === "bar"
    strings.raw[0] === "foo\\n"
    strings.raw[1] === "bar"
    values[0] === 42
}

quux `foo\n${ 42 }bar`

String.raw `foo\n${ 42 }bar` === "foo\\n42bar"

我浏览了以下文档。

http://es6-features.org/#RawStringAccess

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw

http://www.2ality.com/2015/01/es6-strings.html

https://msdn.microsoft.com/en-us/library/dn889830(v=vs.94).aspx

我唯一理解的是,它用于获取模板字符串的原始字符串形式并用于调试模板字符串。

什么时候可以在实时开发中使用?他们称之为标签功能。这意味着什么?

我错过了哪些具体的用例?

4

7 回答 7

19

我能想到的最好的,也是几乎唯一的用例String.raw是,如果您尝试使用像 Steven Levithan 的XRegExp这样的东西,它接受带有显着反斜杠的文本。UsingString.raw可以让你写出语义清晰的东西,而不必考虑加倍反斜杠,就像你可以在 JavaScript 本身的正则表达式文字中一样。

例如,假设我在一个站点上进行维护,我发现:

var isSingleUnicodeWord = /^\w+$/;

...这是为了检查一个字符串是否只包含“字母”。两个问题: A)人类语言领域有成千上万个\w无法识别的“单词”字符,因为它的定义是以英语为中心的;和 B) 它包括_,许多人(包括 Unicode 联盟)认为这不是“字母”。

因此,如果我们在XRegExp网站上使用,因为我知道它支持\pL\p对于 Unicode 类别和L“字母”),我可能会很快将其换成:

var isSingleUnicodeWord = XRegExp("^\pL+$"); // WRONG

然后我想知道为什么它不起作用,facepalm,然后返回并逃避那个反斜杠,因为它被字符串文字所消耗。

在那个简单的正则表达式中很容易,但在一些复杂的情况下,记住将所有这些反斜杠加倍是一种维护痛苦。(只需询问尝试使用 . 的 Java 程序员即可Pattern。)

输入String.raw

let isSingleUnicodeWord = XRegExp(String.raw`^\pL+$`);

例子:

let isSingleUnicodeWord = XRegExp(String.raw`^\pL+$`); // L: Letter
console.log(isSingleUnicodeWord.test("Русский"));      // true
console.log(isSingleUnicodeWord.test("日本語"));        // true
console.log(isSingleUnicodeWord.test("العربية"));      // true
console.log(isSingleUnicodeWord.test("foo bar"));      // false
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.min.js"></script>

现在我只是回过头来写下我的意思。我什至不必担心${...}模板文字中使用的构造来进行替换,因为我想将量词{...}应用于行尾断言 ( $) 的可能性...很低。所以我可以愉快地使用替换而不用担心反斜杠。迷人的。


话虽如此,但如果我经常这样做,我可能想编写一个函数并使用标记模板而不是String.raw它本身。但是正确地做却令人惊讶地尴尬:

// My one-time tag function
function xrex(strings, ...values) {
  let raw = strings.raw;
  let max = Math.max(raw.length, values.length);
  let result = "";
  for (let i = 0; i < max; ++i) {
    if (i < raw.length) {
      result += raw[i];
    }
    if (i < values.length) {
      result += values[i];
    }
  }
  console.log("Creating with:", result);
  return XRegExp(result);
}

// Using it, with a couple of substitutions to prove to myself they work
let category = "L";                                // L: Letter
let maybeEol = "$";
let isSingleUnicodeWord = xrex`^\p${category}+${maybeEol}`;
console.log(isSingleUnicodeWord.test("Русский"));  // true
console.log(isSingleUnicodeWord.test("日本語"));    // true
console.log(isSingleUnicodeWord.test("العربية"));  // true
console.log(isSingleUnicodeWord.test("foo bar"));  // false
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.min.js"></script>

如果您在很多地方使用它,也许这些麻烦是值得的,但对于几个快速的地方,String.raw这是更简单的选择。

于 2016-08-07T17:16:20.997 回答
3

模板字符串在许多情况下都很有用,我将在下面解释。考虑到这一点,String.raw 可以防止转义被解释。这在您想要包含转义字符但不想对其进行转义的任何模板字符串中都很有用。一个简单的例子如下:

var templateWithBackslash = String.raw `someRegExp displayed in template /^\//`

里面有一些东西很好用模板字符串注意。

  1. 它们可以包含未转义的换行符而不会出现问题。
  2. 它们可以包含“${}”。在这些花括号内,javascript 被解释。

(注意:运行这些会将结果输出到您的控制台[在浏览器开发工具中])

使用换行符的示例:

var myTemplate = `
<div class="myClass">
  <pre>
    My formatted text
    with multiple lines
    {
      asdf: "and some pretty printed json"
    }
  </pre>
</div>
`
console.log(myTemplate)

如果您想在 Javascript 中使用普通字符串执行上述操作,则如下所示:

var myTemplate = "\
<div class="myClass">\
  <pre>\
    My formatted text\
    with multiple lines\
    {\
      asdf: "and some pretty printed json"\
    }\
  </pre>\
</div>"
console.log(myTemplate)

您会注意到第一个可能看起来更好(无需转义换行符)。

第二个我将使用相同的模板字符串,但也会插入一些漂亮的打印 JSON。

var jsonObj = {asdf: "and some pretty printed json", deeper: {someDeep: "Some Deep Var"}}
var myTemplate = `
<div class="myClass">
  <pre>
    My formatted text
    with multiple lines
    ${JSON.stringify(jsonObj, null, 2)}
  </pre>
</div>
`
console.log(myTemplate)

于 2016-01-14T00:51:49.883 回答
3

首先,有几点:

  • 模板字符串是模板文字的旧名称。
  • 标签是一个函数。
  • String.raw 是一种方法。
  • String.raw `foo\n${ 42 }bar\`是一个标记的模板文字。
  • 模板文字基本上是花哨的字符串。
  • 模板文字可以插值。
  • 模板文字可以是多行而不使用\.
  • String.raw 需要转义转义字符\

尝试通过使用换行符的函数放置一个包含\n换行符的字符串。

console.log("This\nis\nawesome"); // "This\nis\nawesome"
console.log(String.raw`This\nis\nawesome`); // "This\\nis\\nawesome"

如果您想知道,console.log 不是其中之一。但是alert是。尝试通过http://learnharmony.org/运行这些。

alert("This\nis\nawesome");
alert(String.raw`This\nis\nawesome`);

但是等等,这不是String.raw.

方法的可能用途String.raw

  • 在不解释反斜杠字符(\n、\t)等的情况下显示字符串。
  • 显示输出的代码。(如下例所示)
  • 用于正则表达式而不转义\
  • \\无需使用太多即可打印 windows 目录/子目录位置。(他们使用\记住。另外,大声笑)

在这里,我们可以在单个警报窗口中显示输出和代码:

alert("I printed This\nis\nawesome with " + Sring.raw`This\nis\nawesome`);

不过,如果它的主要用途是取回原始字符串,那就太好了。像:

var original = String.raw`This    is     awesome.`;

哪里original会变成:This\tis \tawesome.。可悲的是,情况并非如此。

参考:

于 2016-02-11T15:23:50.023 回答
1

在 NodeJS 中,当涉及到文件路径处理时,它非常方便:

var fs=require('fs');
var s =  String.raw`C:\Users\<username>\AppData\Roaming\SomeApp\someObject.json`;
var username = "bob"
s=s.replace("<username>",username)
fs.readFile(s,function(err,result){
    if (err) throw error;
    console.log(JSON.parse(result))
})

它提高了 Windows 上文件路径的可读性。\也是一个相当常见的分隔符,所以我绝对可以理解为什么它通常很有用。然而,如何\仍然逃脱是非常愚蠢的`......所以最终:

String.raw`C:\Users\` //#==> C:\Users\`
console.log(String.raw`C:\Users\`) //#==> SyntaxError: Unexpected end of input.
于 2017-05-25T10:07:54.840 回答
0

使用

(必备知识:tstring §。)

代替:

console.log(`\\a\\b\\c\\n\\z\\x12\\xa9\\u1234\\u00A9\\u{1234}\\u{00A9}`); 

。你可以:

console.log(String.raw`\a\b\c\n\z\x12\xa9\u1234\u00A9\u{1234}\u{00A9}`);

“逃跑”

< \\u> 很好,但 < \u> 需要“转义”,例如:

console.log(String.raw`abc${'\\u'}abc`);

.Dit < \\x>, < \x>, < console.log(String.raw`abc${`\\x`}abc`)>;

.< \`>, < `>, < console.log(String.raw`abc${`\``}abc`)>;

.< \${>, < ${&>, < console.log(String.raw`abc${`$\{`}abc`)>;

.< \\1> (直到 < \\7>), < \1>, < console.log(String.raw`abc${`\\1`}abc`)>;

.< \\>,endunit < \>,< console.log(String.raw`abc${`\\`}`)>。


还有一个新的“乳胶”字符串。参见§

于 2017-06-17T17:44:43.303 回答
0

我发现它对测试我的 RegExps 很有用。假设我有一个 RegExp 应该匹配行尾注释,因为我想删除它们。但是,它不能匹配像 /// 这样的正则表达式的源代码。如果您的代码包含 /// 它不是 EOL 注释的开头而是 RegExp,根据 JavaScript 语法规则。

我可以测试变量 patEOLC 中的 RegExp 是否匹配 /// 与:

String.raw`/\//` .match (patEOLC)

换句话说,这是一种让我的代码“看到”代码在源代码中存在的方式的方法,而不是在从源代码读入内存后它在内存中存在的方式,所有反斜杠都被删除。

这是一种“转义转义”的方法,但不必对字符串中的每个反斜杠单独进行,而是同时对所有反斜杠进行。

这是一种说法,在给定的(反引号)字符串中,反斜杠的行为就像任何其他字符一样,它没有特殊的含义或解释。

于 2018-09-11T21:14:05.737 回答
0

除了用作标签之外,String.raw它还有助于实现新的标签功能,作为一种工具来完成大多数人用奇怪循环所做的交错。例如,比较:

function foo(strs, ...xs) {
    let result = strs[0];
    for (let i = 0; i < xs.length; ++i) {
      result += useFoo(xs[i]) + strs[i + 1];
    }
    return result;
}

function foo(strs, ...xs) {
    return String.raw({raw: strs}, ...xs.map(useFoo));
}
于 2021-06-11T19:57:14.453 回答