Użycie znaku backtick (`) w JavaScript


277

W JavaScripcie † wydaje się działać tak samo jak pojedynczy cytat. Na przykład mogę użyć znaku wstecznego, aby zdefiniować ciąg taki jak ten:

var s = `abc`;

Czy istnieje sposób, w jaki zachowanie backticka faktycznie różni się od zachowania pojedynczego cytatu?


† Zauważ, że wśród programistów „backtick” to jedna z nazw tego, co jest bardziej ogólnie nazywane poważnym akcentem . Programiści czasami używają alternatywnych nazw „backquote” i „backgrave”. Również w stosie przepełnienia stosu i gdzie indziej, inne popularne pisowni dla „backtick” to „back-tick” i „back tick”.


Przeczytaj także poniżej o korzystaniu z Tagged Templates. Jest to inne zastosowanie niż zadawane pytanie. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… I to wyjaśniono w jednej z dłuższych odpowiedzi poniżej. stackoverflow.com/a/40062505/3281336
— PatS

1
„Backgrave” jest absurdalny, ponieważ nie ma przedniego poważnego akcentu - to się nazywa ostry akcent
— Walter Tross

Odpowiedzi:


297

Jest to funkcja zwana literałami szablonów .

Były one nazywane „ciągami szablonów” we wcześniejszych wydaniach specyfikacji ECMAScript 2015.

Literały szablonów są obsługiwane przez przeglądarki Firefox 34, Chrome 41 i Edge 12 i nowsze, ale nie przez Internet Explorer.

Literały szablonowe mogą być używane do reprezentowania ciągów wieloliniowych i mogą wykorzystywać „interpolację” do wstawiania zmiennych:

var a = 123, str = `---
   a is: ${a}
---`;
console.log(str);

Wynik:

---
   a is: 123
---

Co ważniejsze, mogą zawierać nie tylko nazwę zmiennej, ale dowolne wyrażenie JavaScript:

var a = 3, b = 3.1415;

console.log(`PI is nearly ${Math.max(a, b)}`);

2
Czy istnieją jakieś realne polifile na to, biorąc pod uwagę brak wsparcia?
— Alexander Dixon

3
@AlexanderDixon, no nie można PolyFill tę funkcję języka w klasycznym tego słowa znaczeniu, choć można użyć szablonów z podkreśleniem lub lodash dla zmiennych w ciągach w połączeniu z wykorzystaniem tablic multilining ciągi: ["a", "b"].join(""); // both string elements written in new lines. Ale oprócz tego można użyć „transpilatora”, takiego jak Babel, aby przekonwertować ES6 + na ES5
— spróbuj złapać w końcu

2
Otagowano literały szablonów za pomocą wstecznych! Jest to ważny i działa dobrze:alert`1`.
— Константин Ван

@UnionP Obsługiwane przez wszystkie główne przeglądarki, w tym MS Edge: kangax.github.io/compat-table/es6/#test-template_literals
— Jonathan Cross

2
@kiki wygląda na to, że język skryptowy jest odmianą ECMAScript. Oczywiście skrypty aplikacji Google nie obsługują funkcji ECMAScript 2015. Nie mogłem znaleźć oficjalnej specyfikacji, jakiego języka używają.
— spróbuj złapać w końcu

162

ECMAScript 6 oferuje nowy typ literału łańcuchowego, wykorzystujący backstick jako separator. Te literały pozwalają na osadzenie podstawowych wyrażeń interpolacyjnych, które są następnie automatycznie analizowane i analizowane.

let person = {name: 'RajiniKanth', age: 68, greeting: 'Thalaivaaaa!' };

let usualHtmlStr = "<p>My name is " + person.name + ",</p>\n" +
  "<p>I am " + person.age + " old</p>\n" +
  "<strong>\"" + person.greeting + "\" is what I usually say</strong>";

let newHtmlStr =
 `<p>My name is ${person.name},</p>
  <p>I am ${person.age} old</p>
  <p>"${person.greeting}" is what I usually say</strong>`;

console.log(usualHtmlStr);
console.log(newHtmlStr);

Jak widać, użyliśmy `około szeregu znaków, które są interpretowane jako dosłowny ciąg znaków, ale wszelkie wyrażenia formy ${..}są analizowane i przetwarzane bezpośrednio w tekście.

Jedną naprawdę fajną zaletą interpolowanych literałów łańcuchowych jest to, że mogą one dzielić się na wiele linii:

var Actor = {"name": "RajiniKanth"};

var text =
`Now is the time for all good men like ${Actor.name}
to come to the aid of their
country!`;
console.log(text);
// Now is the time for all good men
// to come to the aid of their
// country!

Wyrażenia interpolowane

Dowolne prawidłowe wyrażenie może pojawiać się wewnątrz ${..}interpolowanego literału łańcuchowego, w tym wywołania funkcji, wbudowane wywołania wyrażenia funkcyjnego, a nawet inne interpolowane łańcuchy literalne!

function upper(s) {
  return s.toUpperCase();
}
var who = "reader"
var text =
`A very ${upper("warm")} welcome
to all of you ${upper(`${who}s`)}!`;
console.log(text);
// A very WARM welcome
// to all of you READERS!

Tutaj wewnętrzny `${who}s`interpolowany literał łańcuchowy był dla nas nieco przyjemniejszy, gdy łączyliśmy whozmienną z "s"łańcuchem, w przeciwieństwie do who + "s". Aby zachować notatkę, interpolowany łańcuch literalny jest po prostu leksykalny o zasięgu, w którym się pojawia, a nie dynamicznie w żaden sposób:

function foo(str) {
  var name = "foo";
  console.log(str);
}
function bar() {
  var name = "bar";
  foo(`Hello from ${name}!`);
}
var name = "global";
bar(); // "Hello from bar!"

Używanie szablonu HTML w literaturze jest zdecydowanie bardziej czytelne dzięki zmniejszeniu irytacji.

Prosty stary sposób:

'<div class="' + className + '">' +
  '<p>' + content + '</p>' +
  '<a href="' + link + '">Let\'s go</a>'
'</div>';

Z ECMAScript 6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
  • Twój ciąg może obejmować wiele linii.
  • Nie musisz uciekać znaków cudzysłowu.
  • Możesz uniknąć grupowania takich jak: „”> ”
  • Nie musisz używać operatora plus.

Oznaczone literały szablonów

Możemy również otagować ciąg szablonu, gdy ciąg szablonu jest oznakowany, literały i podstawienia są przekazywane do funkcji, która zwraca wynikową wartość.

function myTaggedLiteral(strings) {
  console.log(strings);
}

myTaggedLiteral`test`; //["test"]

function myTaggedLiteral(strings, value, value2) {
  console.log(strings, value, value2);
}
let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

Możemy tutaj użyć operatora rozkładania, aby przekazać wiele wartości. Pierwszy argument - nazwaliśmy go łańcuchami - to tablica wszystkich prostych łańcuchów (między dowolnymi interpolowanymi wyrażeniami).

Następnie zebrać wszystkie kolejne argumenty do tablicy zwanych wartości używając ... gather/rest operator, choć może oczywiście nie zostawili je jako pojedyncze nazwanych parametrów następujących ciągów parametrów jak zrobiliśmy powyżej ( value1, value2etc.).

function myTaggedLiteral(strings, ...values) {
  console.log(strings);
  console.log(values);
}

let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

Argumenty zebrane w naszej tablicy wartości są wynikami już ocenionych wyrażeń interpolacyjnych znalezionych w literale ciągu. Znakowany literał łańcucha jest jak etap przetwarzania po ocenie interpolacji, ale przed skompilowaniem końcowej wartości ciągu, co pozwala na większą kontrolę nad generowaniem łańcucha z literału. Spójrzmy na przykład tworzenia szablonów wielokrotnego użytku.

const Actor = {
  name: "RajiniKanth",
  store: "Landmark"
}

const ActorTemplate = templater`<article>
  <h3>${'name'} is a Actor</h3>
  <p>You can find his movies at ${'store'}.</p>

</article>`;

function templater(strings, ...keys) {
  return function(data) {
    let temp = strings.slice();
    keys.forEach((key, i) => {
      temp[i] = temp[i] + data[key];
    });
    return temp.join('');
  }
};

const myTemplate = ActorTemplate(Actor);
console.log(myTemplate);

Surowe struny

Nasze funkcje znaczników otrzymują pierwszy argument, który nazywamy ciągami, którym jest tablica. Ale zawiera dodatkowy bit danych: nieprzetworzone nieprzetworzone wersje wszystkich ciągów. Możesz uzyskać dostęp do tych nieprzetworzonych wartości ciągów za pomocą .rawwłaściwości:

function showraw(strings, ...values) {
  console.log(strings);
  console.log(strings.raw);
}
showraw`Hello\nWorld`;

Jak widać, nieprzetworzona wersja ciągu zachowuje \nsekwencję zmiany znaczenia, a przetworzona wersja ciągu traktuje go jak prawdziwą nową linię bez zmian. ECMAScript 6 pochodzi z wbudowanej funkcji, które mogą być używane jako znak ciągiem znaków: String.raw(..). Po prostu przechodzi przez surowe wersje ciągów:

console.log(`Hello\nWorld`);
/* "Hello
World" */

console.log(String.raw`Hello\nWorld`);
// "Hello\nWorld"

1
Świetna odpowiedź! Drobny komentarz, w twojej sekcji Tagged Template Literals uważam, że dwa przykładowe dane wyjściowe tablicy myTaggedLiteral`test ${someText} ${2 + 3}`;powinny być //["test ", " "](tzn. Nie przycięte ciągi znaków).
— Michael Krebs

3
Przewinął w dół, aby zobaczyć konto autora, nie był rozczarowany! Dobre wytłumaczenie. xD
— var

Dobre wyjaśnienie i szeroki zasięg, dziękuję. Chciałem tylko dodać, że istnieje także dobry przegląd strony dewelopera Mozilli. Literały szablonów (ciągi szablonów), które obejmują kilka dodatkowych aspektów.
— Dev Ops

1
Nit: „ECMAScript 6 proponuje nowy typ literału ciągów” To nie jest literał ciągów, to dosłowny szablon. Wynik jest oceniany, jeśli nie jest oznaczony. Nie jest to tylko dogmatyczne, istnieją miejsca, w których można używać literałów łańcuchowych, w których literały szablonów są niedozwolone (takie jak nieobliczone nazwy parametrów, identyfikatory modułów ...).
— TJ Crowder

Zdanie zawierające „jest interpolowanym dosłownym ciągiem literowym ma jedynie leksykalny zasięg” jest niezrozumiałe. Czy możesz to naprawić?
— Peter Mortensen

21

Backticks ( `) służą do definiowania literałów szablonów. Literały szablonów to nowa funkcja w ECMAScript 6, która ułatwia pracę z łańcuchami.

Cechy:

  • możemy interpolować dowolny rodzaj wyrażenia w literałach szablonu.
  • Mogą być wieloliniowe.

Uwaga: możemy łatwo używać pojedynczych cudzysłowów ( ') i podwójnych cudzysłowów ( ") w backticks ( `).

Przykład:

var nameStr = `I'm "Rohit" Jindal`;

Aby interpolować zmienne lub wyrażenie, możemy do tego użyć ${expression}zapisu.

var name = 'Rohit Jindal';
var text = `My name is ${name}`;
console.log(text); // My name is Rohit Jindal

Ciągi wielowierszowe oznaczają, że nie musisz już używać \nnowych linii.

Przykład:

const name = 'Rohit';
console.log(`Hello ${name}!
How are you?`);

Wynik:

Hello Rohit!
How are you?

15

Backticks otaczają literały szablonów, wcześniej znane jako ciągi szablonów. Literały szablonów są literałami ciągów, które umożliwiają osadzanie wyrażeń i interpolację ciągów.

Literały szablonów mają wyrażenia osadzone w symbolach zastępczych, oznaczone znakiem dolara i nawiasami klamrowymi wokół wyrażenia, tj ${expression}. Symbol zastępczy / wyrażenia są przekazywane do funkcji. Domyślna funkcja po prostu łączy łańcuch.

Aby uniknąć ucieczki, umieść przed nią odwrotny ukośnik:

`\`` === '`'; => true

Użyj kursorów tylnych, aby łatwiej pisać ciągi wieloliniowe:

console.log(`string text line 1
string text line 2`);

lub

console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);

vs. waniliowy JavaScript:

console.log('string text line 1\n' +
'string text line 2');

lub

console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');

Sekwencje ewakuacyjne:

  • Unicode ucieka rozpoczęty przez \u, na przykład\u00A9
  • Punkty kodowe Unicode są oznaczone znakiem ucieczki \u{}, na przykład\u{2F804}
  • \xNa przykład ucieczki szesnastkowe\xA9
  • Ucieczki ósemkowe dosłownie rozpoczęte na przykład przez \(a) cyfrę (y)\251

10

Podsumowanie:

Backticks w JavaScript to funkcja, która została wprowadzona w ECMAScript 6 // ECMAScript 2015 w celu tworzenia łatwych ciągów dynamicznych. Ta funkcja ECMAScript 6 jest również nazywana literałem ciągu znaków . Oferuje następujące zalety w porównaniu z normalnymi łańcuchami:

  • W ciągach szablonów dozwolone są podziały wierszy, a zatem mogą być wielowierszowe. Normalne literały łańcuchowe (zadeklarowane za pomocą ''lub "") nie mogą mieć podziałów wierszy.
  • Możemy łatwo interpolować wartości zmiennych do łańcucha za pomocą ${myVariable}składni.

Przykład:

const name = 'Willem';
const age = 26;

const story = `
  My name is: ${name}
  And I'm: ${age} years old
`;

console.log(story);

Kompatybilność z przeglądarkami:

Dosłowne ciągi szablonów są natywnie obsługiwane przez wszystkich głównych dostawców przeglądarek (oprócz Internet Explorera). Jest więc dość bezpieczny w użyciu w kodzie produkcyjnym. Bardziej szczegółową listę kompatybilności przeglądarki można znaleźć tutaj .


10

Oprócz interpolacji łańcuchów, możesz także wywołać funkcję za pomocą back-tick.


var sayHello = function () {
    console.log('Hello', arguments);
}

// To call this function using ``

sayHello`some args`; // Check console for the output

// Or
sayHello`
    some args
`;

Sprawdź stylizowany komponent . Używają go intensywnie.


7

Najlepsze jest to, że możemy tworzyć podstawowe matematyki bezpośrednio:

let nuts = 7

more.innerHTML = `

<h2>You collected ${nuts} nuts so far!

<hr>

Double it, get ${nuts + nuts} nuts!!

`
<div id="more"></div>

Stał się naprawdę przydatny w funkcji fabrycznej:

function nuts(it){
  return `
    You have ${it} nuts! <br>
    Cosinus of your nuts: ${Math.cos(it)} <br>
    Triple nuts: ${3 * it} <br>
    Your nuts encoded in BASE64:<br> ${btoa(it)}
  `
}

nut.oninput = (function(){
  out.innerHTML = nuts(nut.value)
})
<h3>NUTS CALCULATOR
<input type="number" id="nut">

<div id="out"></div>


3
nikt już nie chichotał cmon
— StayCool
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.