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”.

vancewang
źródło
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)}`);
try-catch-wreszcie
źródło
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"
Thalaivar
źródło
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?
Rohit Jindal
źródło
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
mrmaclean89
źródło
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 .

Willem van der Veen
źródło
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.

Ankit Kumar
źródło
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>

NVRM
źródło
3
nikt już nie chichotał cmon
StayCool