JavaScript'deki dizelerin geçmişte sınırlı olması, Python veya Ruby gibi dillerden beklenen özelliklerin eksik olmasından kaynaklanıyordu. ES6 Şablon Dizeleri (Chrome 41 ve sonraki sürümlerde kullanılabilir), bu durumu temelden değiştirir. Alana özgü diller (DSL'ler) ile dize tanımlamanın bir yolunu sunarak aşağıdakileri iyileştirir:
- Dize kesme
- Yerleştirilmiş ifadeler
- Kod hilesi içermeyen çok satırlık dizeler
- Dize biçimlendirme
- Güvenli HTML kaçış karakteri ekleme, yerelleştirme ve daha fazlası için dize etiketleme.
Şablon dizelerinde, günümüzde bildiğimiz dizelerin içine başka bir özellik daha eklemek yerine bu sorunları çözmenin tamamen farklı bir yolu sunulur.
Söz dizimi
Şablon dizelerinde, normal dizelerde alışkın olduğumuz tek veya çift tırnak yerine ters tırnak (``) kullanılır. Bu nedenle, bir şablon dizesi aşağıdaki gibi yazılabilir:
var greeting = `Yo World!`;
Şablon dizelerinin bize normal dizelerden daha fazla bir şey sunmadığını düşünüyoruz. Bu durumu değiştirelim.
Dize Değiştirme
Bu tür araçların ilk gerçek avantajlarından biri dize değiştirmedir. Değişim, herhangi bir geçerli JavaScript ifadesini (değişken ekleme dahil) almamıza olanak tanır ve sonuç, bir Şablon Dize içinde aynı dizenin bir parçası olarak gösterilir.
Şablon dizelerinde, aşağıdaki gibi ${ }
söz dizimi kullanılarak dize değiştirme için yer tutucular bulunabilir:
// Simple string substitution
var name = "Brendan";
console.log(`Yo, ${name}!`);
// => "Yo, Brendan!"
Şablon dizelerindeki tüm dize değiştirme işlemleri JavaScript ifadeleri olduğundan değişken adlarından çok daha fazlasını değiştirebiliriz. Örneğin, aşağıdaki satır içi matematik ifadesi için ifade ayrıştırmasını kullanabiliriz:
var a = 10;
var b = 10;
console.log(`JavaScript first appeared ${a+b} years ago. Wow!`);
//=> JavaScript first appeared 20 years ago. Wow!
console.log(`The number of JS MVC frameworks is ${2 * (a + b)} and not ${10 * (a + b)}.`);
//=> The number of JS frameworks is 40 and not 200.
Ayrıca, ifadeler içindeki işlevler için de çok faydalıdırlar:
function fn() { return "I am a result. Rarr"; }
console.log(`foo ${fn()} bar`);
//=> foo I am a result. Rarr bar.
${}
, üye ifadeleri ve yöntem çağrıları dahil olmak üzere her türlü ifadeyle sorunsuz çalışır:
var user = {name: 'Caitlin Potter'};
console.log(`Thanks for getting this into V8, ${user.name.toUpperCase()}.`);
// => "Thanks for getting this into V8, CAITLIN POTTER";
// And another example
var thing = 'template strings';
console.log(`Say hello to ${thing}.`);
// => Say hello to template strings
Dizenizde ters eğik çizgiye ihtiyacınız varsa ters eğik çizgi karakteri \
kullanılarak kod dışına alınabilir.
var greeting = `\`Yo\` World!`;
Çok Satırlı Dize
JavaScript'teki çok satırlık dizelerin kullanımı için bir süredir geçici çözümler gerekiyordu. Bu sorunlara yönelik mevcut çözümler, dizelerin tek bir satırda bulunmasını veya her yeni satırdan önce \
(ters eğik çizgi) kullanılarak çok satırlı dizelere bölünmesini gerektirir. Örneğin:
var greeting = "Yo \
World";
Bu yöntem, çoğu modern JavaScript motorunda sorunsuz şekilde çalışsa da davranışın kendisi hâlâ biraz hile niteliğindedir. Çok satırlık desteği taklit etmek için dize birleştirme de kullanılabilir ancak bu da istenilen sonucu vermez:
var greeting = "Yo " +
"World";
Şablon dizeleri, çok satırlık dizeleri önemli ölçüde basitleştirir. İhtiyaç duyulan yerlere yeni satır eklemeniz yeterlidir. Aşağıda bununla ilgili bir örnek verilmiştir:
Ters tırnak içine alınmış dizelerdeki boşluklar da dizenin bir parçası olarak kabul edilir.
console.log(`string text line 1
string text line 2`);
Etiketli Şablonlar
Şimdiye kadar, dize değiştirme ve çok satırlık dize oluşturma için Şablon Dizelerini kullanmayı inceledik. Etiketli şablonlar da bu sürümde kullanıma sunulan güçlü özelliklerden biridir. Etiketli şablonlar, şablon dizesinin önüne bir işlev adı yerleştirerek şablon dizesini dönüştürür. Örneğin:
fn`Hello ${you}! You're looking ${adjective} today!`
Etiketlenmiş şablon dizeninin semantikleri, normal bir şablon dizeninin semantiklerinden çok farklıdır. Özünde, bunlar özel bir işlev çağrısı türüdür: Yukarıdaki ifade
fn(["Hello ", "! You're looking ", " today!"], you, adjective);
(n + 1)inci bağımsız değişkenin, dize dizisindeki n. ve (n + 1)inci girişler arasında gerçekleşen ikame işlemine nasıl karşılık geldiğini unutmayın. Bu, her türlü şey için yararlı olabilir ancak en basit kullanımlarından biri, tüm içe yerleştirilmiş değişkenlerin otomatik olarak kaçırılmasıdır.
Örneğin, HTML'den kaçan bir işlev yazabilirsiniz.
html`<p title="${title}">Hello ${you}!</p>`
uygun değişkenlerin yerine geçtiği ancak HTML için güvenli olmayan tüm karakterlerin değiştirildiği bir dize döndürür. Haydi öyle yapalım. HTML'den kaçınma işlevimiz iki bağımsız değişken alır: kullanıcı adı ve yorum. Her ikisi de HTML için güvenli olmayan karakterler (yani ', ", <, > ve &) içerebilir. Örneğin, kullanıcı adı "Domenic Denicola" ve yorum "& eğlenceli bir etikettir" ise şu çıktıyı vermemiz gerekir:
<b>Domenic Denicola says:</b> "& is a fun tag"
Etiketli şablon çözümümüz aşağıdaki gibi yazılabilir:
// HTML Escape helper utility
var util = (function () {
// Thanks to Andrea Giammarchi
var
reEscape = /[&<>'"]/g,
reUnescape = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g,
oEscape = {
'&': '&',
'<': '<',
'>': '>',
"'": ''',
'"': '"'
},
oUnescape = {
'&': '&',
'&': '&',
'<': '<',
'<': '<',
'>': '>',
'>': '>',
''': "'",
''': "'",
'"': '"',
'"': '"'
},
fnEscape = function (m) {
return oEscape[m];
},
fnUnescape = function (m) {
return oUnescape[m];
},
replace = String.prototype.replace
;
return (Object.freeze || Object)({
escape: function escape(s) {
return replace.call(s, reEscape, fnEscape);
},
unescape: function unescape(s) {
return replace.call(s, reUnescape, fnUnescape);
}
});
}());
// Tagged template function
function html(pieces) {
var result = pieces[0];
var substitutions = [].slice.call(arguments, 1);
for (var i = 0; i < substitutions.length; ++i) {
result += util.escape(substitutions[i]) + pieces[i + 1];
}
return result;
}
var username = "Domenic Denicola";
var tag = "& is a fun tag";
console.log(html`<b>${username} says</b>: "${tag}"`);
//=> <b>Domenic Denicola says</b>: "& is a fun tag"
Diğer olası kullanımlar arasında otomatik kaçış, biçimlendirme, yerelleştirme ve genel olarak daha karmaşık ikameler yer alır:
// Contextual auto-escaping
qsa`.${className}`;
safehtml`<a href="${url}?q=${query}" onclick="alert('${message}')" style="color: ${color}">${message}</a>`;
// Localization and formatting
l10n`Hello ${name}; you are visitor number ${visitor}:n! You have ${money}:c in your account!`
// Embedded HTML/XML
jsx`<a href="${url}">${text}</a>` // becomes React.DOM.a({ href: url }, text)
// DSLs for code execution
var childProcess = sh`ps ax | grep ${pid}`;
Özet
Şablon dizelerini Chrome 41 beta ve sonraki sürümlerde, IE Tech Preview'de, Firefox 35 ve sonraki sürümlerde ve io.js'de kullanabilirsiniz. Pratikte, bunları şu anda üretimde kullanmak istiyorsanız Traceur ve 6to5 gibi başlıca ES6 derleyicilerinde desteklenirler. Bunları denemek isterseniz Chrome örnekleri deposundaki Şablon dizesi örneğimize göz atın. ES5'te ES6 Eşdeğerlerini de inceleyebilirsiniz. Bu makalede, günümüzde ES5'te şablon dizelerinin sunduğu bazı kolaylıkların nasıl elde edileceği gösterilmektedir.
Şablon dizelerinin JavaScript'e birçok önemli özelliği kazandırdığını biliyor muydunuz? Bunlar arasında dize ve ifade ayrıştırma, çok satırlık dize ve kendi DSL'lerinizi oluşturma gibi daha iyi yöntemler yer alıyor.
Bu araçlarda sunulan en önemli özelliklerden biri, etiketli şablonlardır. Bu şablonlar, bu tür DSL'leri oluşturmak için kritik bir özelliktir. Bu işlevler, bir şablon dizenin bölümlerini bağımsız değişken olarak alır. Ardından, dizenizin nihai çıktısını belirlemek için dizelerin ve değiştirmelerin nasıl kullanılacağına karar verebilirsiniz.