es6 - template string javascript
¿Cuáles son los usos reales de ES6 Raw String Access? (6)
¿Cuáles son los usos reales de String.raw
Raw String Access introducido en ECMAScript 6?
// 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"
Pasé por los siguientes documentos.
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
Lo único que entiendo es que se usa para obtener la forma de cadena sin procesar de las cadenas de plantilla y se usa para depurar la cadena de la plantilla.
¿Cuándo se puede utilizar esto en el desarrollo en tiempo real? Estaban llamando a esto una función de etiqueta. Qué significa eso?
¿Qué casos de uso concretos me faltan?
El uso
(Conocimiento requerido: tstring § .)
En lugar de:
console.log(`//a//b//c//n//z//x12//xa9//u1234//u00A9//u{1234}//u{00A9}`);
.usted puede:
console.log(String.raw`/a/b/c/n/z/x12/xa9/u1234/u00A9/u{1234}/u{00A9}`);
"Escapar"
< //u
> está bien, sin embargo, < /u
> necesita "escape", por ejemplo:
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
> (hasta < //7
>), < /1
>, < console.log(String.raw`abc${`//1`}abc`)
>;
. < //
>, endunit < /
>, < console.log(String.raw`abc${`//`}`)
>.
Nótese bien
También hay una nueva cadena de "látex". Cf § .
El mejor, y casi único, caso de uso para String.raw
que se me ocurre es si está tratando de usar algo como la biblioteca XRegExp
Steven Levithan que acepta texto con barras invertidas significativas. El uso de String.raw
permite escribir algo semánticamente claro en lugar de tener que pensar en términos de duplicar sus barras invertidas, al igual que puede hacerlo en una expresión regular literal en el propio JavaScript.
Por ejemplo, supongamos que estoy haciendo mantenimiento en un sitio y encuentro esto:
var isSingleUnicodeWord = /^/w+$/;
... que está destinado a verificar si una cadena contiene solo "letras". Dos problemas: A) Hay miles de caracteres de "palabra" en el ámbito del lenguaje humano que no reconoce, porque su definición está centrada en el inglés; e B) Incluye _
, que muchos (incluido el consorcio Unicode) argumentarían que no es una "letra".
Entonces, si estamos usando XRegExp
en el sitio, ya que sé que admite /pL
( /p
para las categorías Unicode y L
para "letra"), podría intercambiar esto rápidamente en:
var isSingleUnicodeWord = XRegExp("^/pL+$"); // WRONG
Entonces me pregunto por qué no funcionó, salí de la cara, y regresé y escapé de la barra invertida, ya que está siendo consumido por la cadena literal.
Bastante fácil en esa expresión regular, pero en algo complicado, recordar duplicar todas esas barras invertidas es un problema de mantenimiento. (Solo pregunte a los programadores de Java que intentan usar el Pattern
).
Introduzca String.raw
:
let isSingleUnicodeWord = XRegExp(String.raw`^/pL+$`);
Ejemplo:
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>
Ahora solo me relajo y escribo lo que quiero decir. Ni siquiera tengo que preocuparme por las construcciones ${...}
utilizadas en los literales de plantilla para realizar la sustitución, porque las probabilidades de que quiera aplicar un cuantificador {...}
a la afirmación de fin de línea ( $
) estan bajos. Así que felizmente puedo usar sustituciones y aun así no preocuparme por las barras invertidas. Encantador.
Sin embargo, dicho esto, si lo estuviera haciendo mucho, probablemente querría escribir una función y usar una plantilla etiquetada en lugar de String.raw
. Pero es sorprendentemente incómodo hacerlo correctamente:
// 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>
Tal vez la molestia valga la pena si la usas en muchos lugares, pero para un par de rápidas, String.raw
es la opción más simple.
En NodeJS es extremadamente útil cuando se trata del manejo de la ruta de archivo:
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))
})
Mejora la legibilidad de filepaths en Windows. /
también es un separador bastante común, así que definitivamente puedo ver por qué sería útil en general. Sin embargo, es bastante estúpido cómo /
todavía escapa `... Así que en última instancia:
String.raw`C:/Users/` //#==> C:/Users/`
console.log(String.raw`C:/Users/`) //#==> SyntaxError: Unexpected end of input.
He encontrado que es útil para probar mi RegExps. Digamos que tengo un RegExp que debería coincidir con los comentarios de fin de línea porque quiero eliminarlos. PERO, no debe coincidir con el código fuente para una expresión regular como ///. Si su código contiene ///, no es el inicio de un comentario de EOL sino un RegExp, según las reglas de la sintaxis de JavaScript.
Puedo probar si mi RegExp en la variable patEOLC coincide o no con /// con:
String.raw`////` .match (patEOLC)
En otras palabras, es una manera de permitir que mi código "vea" el código de la forma en que existe en el código fuente, no la forma en que existe en la memoria después de haber sido leído en la memoria desde el código fuente, con todas las barras invertidas eliminadas.
Es una forma de "escapar del escape", pero sin tener que hacerlo por separado para cada barra invertida en una cadena, pero para todos ellos al mismo tiempo.
Es una forma de decir que en una barra invertida de una cadena dada (entre comillas inversas) se comportará como cualquier otro personaje, no tiene un significado o interpretación especial.
Las cadenas de plantillas pueden ser útiles en muchas situaciones que explicaré a continuación. Teniendo en cuenta esto, el String.raw evita que los escapes sean interpretados. Esto puede ser útil en cualquier cadena de plantilla en la que desea contener el carácter de escape pero no desea escapar. Un ejemplo simple podría ser el siguiente:
var templateWithBackslash = String.raw `someRegExp displayed in template /^///`
Hay algunas cosas en el interior que son agradables a tener en cuenta con las cadenas de plantilla.
- Pueden contener saltos de línea sin escaparse sin problemas.
- Pueden contener "$ {}". Dentro de estas llaves, el javascript se interpreta en su lugar.
(Nota: ejecutando estos se enviará el resultado a su consola [en las herramientas de desarrollo del navegador])
Ejemplo utilizando saltos de línea:
var myTemplate = `
<div class="myClass">
<pre>
My formatted text
with multiple lines
{
asdf: "and some pretty printed json"
}
</pre>
</div>
`
console.log(myTemplate)
Si quisiera hacer lo anterior con una cadena normal en Javascript, se vería como la siguiente:
var myTemplate = "/
<div class="myClass">/
<pre>/
My formatted text/
with multiple lines/
{/
asdf: "and some pretty printed json"/
}/
</pre>/
</div>"
console.log(myTemplate)
Notará que el primero probablemente se vea mucho mejor (no hay necesidad de escapar de los saltos de línea).
Para el segundo usaré la misma cadena de plantilla, pero también insertaré un JSON bastante impreso.
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)
Primero, algunas cosas:
- Cadenas de plantilla es el nombre antiguo para los literales de plantilla.
- Una etiqueta es una función.
- String.raw es un método.
- String.raw
foo/n${ 42 }bar
es una plantilla etiquetada literal. - Los literales de plantilla son básicamente cuerdas de lujo.
- Los literales de plantilla pueden interpolar.
- Los literales de plantilla pueden ser multilínea sin usar
/
. - String.raw es necesario para escapar del carácter de escape
/
.
Intente colocar una cadena que contenga un carácter de nueva línea /n
través de una función que consume el carácter de nueva línea.
console.log("This/nis/nawesome"); // "This/nis/nawesome"
console.log(String.raw`This/nis/nawesome`); // "This//nis//nawesome"
Si te estás preguntando, console.log no es uno de ellos. Pero alert
es. Intente ejecutar estos a través de http://learnharmony.org/ .
alert("This/nis/nawesome");
alert(String.raw`This/nis/nawesome`);
Pero espera, ese no es el uso de String.raw
.
Posibles usos del método String.raw
:
- Para mostrar una cadena sin la interpretación de los caracteres de barra invertida (/ n, / t) etc.
- Para mostrar el código de la salida. (Como en el ejemplo de abajo)
- Para ser utilizado en expresiones regulares sin escapar
/
. - Para imprimir las ubicaciones del director / subdirectorio de Windows sin usar
//
mucho. (Utilizan/
recordar. También, lol)
Aquí podemos mostrar el resultado y el código en una sola ventana de alerta:
alert("I printed This/nis/nawesome with " + Sring.raw`This/nis/nawesome`);
Sin embargo, hubiera sido genial si su uso principal hubiera sido recuperar la cadena original. Me gusta:
var original = String.raw`This is awesome.`;
donde el original
se hubiera convertido en: This/tis /tawesome.
. Lamentablemente este no es el caso.
Referencias: