ES6 टेंप्लेट स्ट्रिंग की मदद से लिटरल वैल्यू पाना

Addy Osmani
Addy Osmani

JavaScript में स्ट्रिंग की सुविधाएं हमेशा से सीमित रही हैं. इनमें Python या Ruby जैसी भाषाओं की सुविधाएं नहीं मिलती हैं. ES6 टेंप्लेट स्ट्रिंग (Chrome 41 और इसके बाद के वर्शन में उपलब्ध हैं) से, इस प्रोसेस में काफ़ी बदलाव होता है. इनसे, डोमेन के हिसाब से बनी भाषाओं (डीएसएल) की मदद से स्ट्रिंग तय करने का तरीका मिलता है. इससे ये चीज़ें बेहतर होती हैं:

  • स्ट्रिंग इंटरपोलेशन
  • एम्बेड किए गए एक्सप्रेशन
  • हैक के बिना मल्टीलाइन स्ट्रिंग
  • स्ट्रिंग फ़ॉर्मैटिंग
  • सुरक्षित एचटीएमएल एस्केपिंग, स्थानीय भाषा में अनुवाद करने वगैरह के लिए स्ट्रिंग टैगिंग.

आज के स्ट्रिंग फ़ंक्शन में एक और सुविधा जोड़ने के बजाय, टेंप्लेट स्ट्रिंग इन समस्याओं को हल करने का एक नया तरीका पेश करती हैं.

सिंटैक्स

टेंप्लेट स्ट्रिंग में, सिंगल या डबल कोट के बजाय बैक-टिक (``) का इस्तेमाल किया जाता है. इसलिए, टेंप्लेट स्ट्रिंग को इस तरह लिखा जा सकता है:

var greeting = `Yo World!`;

अब तक, टेंप्लेट स्ट्रिंग ने हमें सामान्य स्ट्रिंग से ज़्यादा कुछ नहीं दिया है. आइए, इसे बदलते हैं.

स्ट्रिंग सबस्टिट्यूशन

इनमें से पहला असल फ़ायदा, स्ट्रिंग बदलना है. बदलाव करने की सुविधा की मदद से, हम किसी भी मान्य JavaScript एक्सप्रेशन का इस्तेमाल कर सकते हैं. जैसे, वैरिएबल जोड़ना. साथ ही, टेंप्लेट लिटरल के अंदर, नतीजा उसी स्ट्रिंग के हिस्से के तौर पर आउटपुट होगा.

टेंप्लेट स्ट्रिंग में, ${ } सिंटैक्स का इस्तेमाल करके स्ट्रिंग बदलने के लिए प्लेसहोल्डर शामिल किए जा सकते हैं. इसका उदाहरण यहां दिया गया है:

// Simple string substitution
var name = "Brendan";
console.log(`Yo, ${name}!`);

// => "Yo, Brendan!"

टेंप्लेट स्ट्रिंग में सभी स्ट्रिंग सबस्टिट्यूशन, JavaScript एक्सप्रेशन होते हैं. इसलिए, हम वैरिएबल के नामों के अलावा और भी बहुत कुछ बदल सकते हैं. उदाहरण के लिए, यहां हम एक्सप्रेशन इंटरपोलेशन का इस्तेमाल करके, पढ़े जा सकने वाले कुछ इनलाइन मैथ को एम्बेड कर सकते हैं:

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.

ये एक्सप्रेशन में मौजूद फ़ंक्शन के लिए भी बहुत काम के होते हैं:

function fn() { return "I am a result. Rarr"; }
console.log(`foo ${fn()} bar`);
//=> foo I am a result. Rarr bar.

${} किसी भी तरह के एक्सप्रेशन के साथ काम करता है. इनमें सदस्य एक्सप्रेशन और मेथड कॉल शामिल हैं:

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

अगर आपको अपनी स्ट्रिंग में बैकटिक की ज़रूरत है, तो बैकस्लैश कैरेक्टर \ का इस्तेमाल करके, इसे एस्केप किया जा सकता है. इसके लिए, यह तरीका अपनाएं:

var greeting = `\`Yo\` World!`;

मल्टीलाइन स्ट्रिंग

JavaScript में मल्टीलाइन स्ट्रिंग के लिए, कुछ समय तक हैक किए गए तरीके अपनाने पड़ते थे. इन समस्याओं को हल करने के लिए, ज़रूरी है कि स्ट्रिंग एक लाइन में मौजूद हों या हर नई लाइन से पहले \ (बैकस्लैश) का इस्तेमाल करके, उन्हें मल्टीलाइन स्ट्रिंग में बांटा गया हो. उदाहरण के लिए:

var greeting = "Yo \
World";

हालांकि, यह ज़्यादातर आधुनिक JavaScript इंजन में ठीक से काम करना चाहिए, लेकिन यह तरीका अब भी थोड़ा हैक है. स्ट्रिंग को जोड़ने की सुविधा का इस्तेमाल करके, एक से ज़्यादा लाइन में लिखने की सुविधा का झूठा एहसास भी दिया जा सकता है. हालांकि, इससे भी कुछ समस्याएं आती हैं:

var greeting = "Yo " +
"World";

टेंप्लेट स्ट्रिंग की मदद से, कई लाइन वाली स्ट्रिंग को आसानी से मैनेज किया जा सकता है. बस जहां ज़रूरी हो वहां नई लाइन शामिल करें और 'बूम'. यहां एक उदाहरण दिया गया है:

बैकटिक सिंटैक्स के अंदर मौजूद कोई भी खाली जगह, स्ट्रिंग का हिस्सा भी मानी जाएगी.

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

टैग किए गए टेंप्लेट

अब तक, हमने स्ट्रिंग बदलने और एक से ज़्यादा लाइन वाली स्ट्रिंग बनाने के लिए, टेंप्लेट स्ट्रिंग का इस्तेमाल करने के बारे में जाना है. टैग किए गए टेंप्लेट भी एक बेहतरीन सुविधा है. टैग किए गए टेंप्लेट, टेंप्लेट स्ट्रिंग के पहले फ़ंक्शन का नाम डालकर, टेंप्लेट स्ट्रिंग को बदल देते हैं. उदाहरण के लिए:

fn`Hello ${you}! You're looking ${adjective} today!`

टैग की गई टेंप्लेट स्ट्रिंग का सेमेटिक्स, सामान्य स्ट्रिंग से काफ़ी अलग होता है. असल में, ये एक खास तरह के फ़ंक्शन कॉल होते हैं: ऊपर दिए गए "desugars" में

fn(["Hello ", "! You're looking ", " today!"], you, adjective);

ध्यान दें कि (n + 1)वां आर्ग्युमेंट, स्ट्रिंग कलेक्शन में nवीं और (n + 1)वीं एंट्री के बीच होने वाले बदलाव से मेल खाता है. यह सुविधा कई कामों के लिए फ़ायदेमंद हो सकती है. हालांकि, सबसे आसान काम यह है कि किसी भी इंटरपोलेशन किए गए वैरिएबल को अपने-आप एस्केप कर दिया जाए.

उदाहरण के लिए, एचटीएमएल-एस्केपिंग फ़ंक्शन लिखा जा सकता है, ताकि..

html`<p title="${title}">Hello ${you}!</p>`

सही वैरिएबल की जगह स्ट्रिंग दिखाता है. हालांकि, इसमें एचटीएमएल के लिए असुरक्षित सभी वर्णों को बदल दिया जाता है. चलिए, ऐसा करते हैं. हमारा एचटीएमएल-एस्केपिंग फ़ंक्शन दो आर्ग्युमेंट लेगा: उपयोगकर्ता नाम और टिप्पणी. दोनों में एचटीएमएल के असुरक्षित वर्ण (जैसे, ', ", <, >, और &) हो सकते हैं. उदाहरण के लिए, अगर उपयोगकर्ता नाम "Domenic Denicola" है और टिप्पणी "& एक मज़ेदार टैग है" है, तो हमें यह आउटपुट मिलना चाहिए:

<b>Domenic Denicola says:</b> "&amp; is a fun tag"

टैग किए गए टेंप्लेट का समाधान इस तरह लिखा जा सकता है:

// 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 = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        "'": '&#39;',
        '"': '&quot;'
    },
    oUnescape = {
        '&amp;': '&',
        '&#38;': '&',
        '&lt;': '<',
        '&#60;': '<',
        '&gt;': '>',
        '&#62;': '>',
        '&apos;': "'",
        '&#39;': "'",
        '&quot;': '"',
        '&#34;': '"'
    },
    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>: "&amp; is a fun tag"

इसके अन्य संभावित इस्तेमालों में, अपने-आप एस्केप होना, फ़ॉर्मैटिंग, स्थानीय भाषा में अनुवाद करना, और आम तौर पर, ज़्यादा जटिल बदलाव करना शामिल है:

// 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}`;

खास जानकारी

टेंप्लेट स्ट्रिंग, Chrome 41 बीटा+, IE Tech Preview, Firefox 35+, और io.js में उपलब्ध हैं. अगर आपको इन्हें प्रोडक्शन में इस्तेमाल करना है, तो ये ES6 के मुख्य ट्रांसपाइलर के साथ काम करते हैं. इनमें Traceur और 6to5 शामिल हैं. अगर आपको इन्हें आज़माना है, तो Chrome के सैंपल रिपॉज़िटरी में जाकर, टेंप्लेट स्ट्रिंग का सैंपल देखें. शायद आपको ES5 में ES6 के बराबर के टेंप्लेट स्ट्रिंग भी पसंद आएं. इसमें, ES5 का इस्तेमाल करके, सुगरिंग टेंप्लेट स्ट्रिंग को हासिल करने का तरीका बताया गया है.

टेंप्लेट स्ट्रिंग की मदद से, JavaScript में कई अहम सुविधाएं मिलती हैं. इनमें स्ट्रिंग और एक्सप्रेशन इंटरपोलेशन, मल्टीलाइन स्ट्रिंग, और खुद के डीएसएल बनाने के बेहतर तरीके शामिल हैं.

टैग किए गए टेंप्लेट, इनकी सबसे अहम सुविधाओं में से एक हैं. इस तरह के डीएसएल बनाने के लिए, यह एक ज़रूरी सुविधा है. उन्हें टेंप्लेट स्ट्रिंग के हिस्से, आर्ग्युमेंट के तौर पर मिलते हैं. इसके बाद, स्ट्रिंग के आखिरी आउटपुट का पता लगाने के लिए, स्ट्रिंग और सबस्टिट्यूशन का इस्तेमाल करने का तरीका तय किया जा सकता है.

इसके बारे में और पढ़ें