ES6 टेम्प्लेट लिटरल बनाम कंसट्रेटेड स्ट्रिंग्स


84

मेरे पास एक्मा-स्क्रिप्ट -6 के लिए निम्न कोड है template literals

let person = {name: 'John Smith'};   
let tpl = `My name is ${person.name}.`;    
let MyVar="My name is "+ person.name+".";

console.log("template literal= "+tpl);  
console.log("my variable = "+MyVar);

आउटपुट निम्नानुसार है:

template literal= My name is John Smith.
my variable = My name is John Smith.

यह बेला है। मैंने सटीक अंतर खोजने की कोशिश की, लेकिन यह नहीं पाया, मेरा सवाल यह है कि इन दोनों कथनों में क्या अंतर है,

  let tpl = `My name is ${person.name}.`;    

तथा

  let MyVar = "My name is "+ person.name+".";

मैं पहले से ही स्ट्रिंग प्राप्त करने में सक्षम हूँ MyVarसाथ concatenated person.name, यहाँ तो क्या टेम्पलेट शाब्दिक उपयोग करने के लिए परिदृश्य हो सकता है?


8
अन्य भाषाओं में, समय के बारे में यह एक सामान्य विशेषता है! क्लीनर दिखता है, और यह बहुस्तरीय है।
एलक्लेनर्स

5
सुनिश्चित नहीं हैं कि आप "अंतर" से क्या मतलब है, के रूप में tpl === MyVar? एकमात्र अंतर सिंटैक्स है जो उनके साथ बनाया गया था। ध्यान दें कि, स्ट्रिंग कॉन्टेनेशन के विपरीत टेम्प्लेट, टैग फ़ंक्शन भी प्रदान करते हैं जिनका उपयोग स्वचालित भागने जैसी चीज़ों के लिए किया जा सकता है।
बरगी

आप मूल रूप से पूछते हैं कि स्ट्रिंग प्रक्षेप बनाम स्ट्रिंग संयोजन के बीच अंतर क्या है।
दज्जन पविल्का

जवाबों:


104

यदि आप `Hello ${person.name}`प्रश्न के उदाहरण में केवल प्लेसहोल्डर्स (जैसे ) के साथ टेम्प्लेट शाब्दिक का उपयोग कर रहे हैं , तो इसका परिणाम सिर्फ अवतल तारों के समान है। विशेष रूप से यह बेहतर दिखता है और पढ़ने में आसान है, विशेष रूप से मल्टी-लाइन स्ट्रिंग्स या स्ट्रिंग्स दोनों के लिए 'और "चूंकि आपको उन पात्रों से किसी भी अधिक बचना नहीं है।

पठनीयता एक महान विशेषता है, लेकिन टेम्प्लेट के बारे में सबसे दिलचस्प बात टैग किए गए टेम्पलेट शाब्दिक हैं :

let person = {name: 'John Smith'}; 
let tag = (strArr, name) => strArr[0] + name.toUpperCase() + strArr[1];  
tag `My name is ${person.name}!` // Output: My name is JOHN SMITH!

इस उदाहरण की तीसरी पंक्ति में, एक फ़ंक्शन नाम दिया गया tagहै। टेम्पलेट स्ट्रिंग की सामग्री के कई चर में विभाजित है, कि आप के तर्कों में उपयोग कर सकते हैं tagसमारोह: (का मूल्य इस उदाहरण में शाब्दिक वर्गों strArr[0]है My name isऔर का मूल्य strArr[1]है !) और प्रतिस्थापन ( John Smith)। टेम्पलेट शाब्दिक मूल्यांकन किया जाएगा जो भी tagकाम करता है।

ECMAScript विकि सूचियों कुछ संभव उपयोग के मामलों, स्वचालित रूप से बचने या इनपुट, या स्थानीयकरण एन्कोडिंग की तरह। आप एक टैग फंक्शन बना सकते हैं, जो जर्मन जैसे उदाहरण के msgलिए शाब्दिक भागों को देखता है My name isऔर वर्तमान स्थानीय भाषा में अनुवाद के साथ उन्हें प्रतिस्थापित करता है:

console.log(msg`My name is ${person.name}.`) // Output: Mein Name ist John Smith.

टैग फ़ंक्शन द्वारा लौटाया गया मान स्ट्रिंग होना भी नहीं है। आप एक टैग फ़ंक्शन बना सकते हैं, $जो स्ट्रिंग का मूल्यांकन करता है और डोम नोड्स के संग्रह को वापस करने के लिए एक क्वेरी चयनकर्ता के रूप में इसका उपयोग करता है, जैसे कि इस उदाहरण में :

$`a.${className}[href=~'//${domain}/']`

2
अच्छा! यदि आपके पास एक और टेम्पलेट शाब्दिक था, जैसे $ {person.message}, तो इसका अनुवाद किया जाएगा?
ऋगोट्टी

1
@Rigotti यह msgफ़ंक्शन के कार्यान्वयन तक है । आप निश्चित रूप से प्रतिस्थापन मूल्यों का अनुवाद भी कर सकते हैं।
kapex 15

@Beat पूरे ecmascript.org साइट से लगता है कि यह नीचे है। मुझे लगता है कि उनके पास वैसे भी अपनी विकी को छोड़ने की योजना थी, इसलिए मैंने संग्रहीत संस्करणों के साथ लिंक को अपडेट किया है।
केपेक्स

मैं a.${className}[href=~'//${domain}/']क्रोम कंसोल में $ चलाने की कोशिश करता हूं (और पहले सेट करता हूं className=''और domain=''मुझे डोम नोड्स नहीं मिलते हैं लेकिन स्ट्रिंग्स की सरणी: / (दूसरे हैड में, jsfiddle में हमें कंसोल में त्रुटि मिलती है: jsfiddle.net/d1fitta76 ) बिना किसी संदर्भ के : $ परिभाषित नहीं है "- क्यों?
कामिल Kiełczewski

2
@AniketSuryavanshi यहां टेम्प्लेट स्ट्रिंग्स बनाम कॉन्टेक्टेनशन परफॉर्मेंस की तुलना की गई है: stackoverflow.com/a/29083467/897024 कुछ साल पहले टेम्प्लेट स्ट्रिंग्स धीमी थीं, लेकिन ऐसा लगता है कि वे अब कॉनसैट से थोड़ा तेज़ हैं।
kapex

16

ES6एक नए प्रकार के स्ट्रिंग शाब्दिक के साथ आता है, `बैक-टिक को सीमांकक के रूप में उपयोग करता है। ये शाब्दिक बुनियादी स्ट्रिंग प्रक्षेप अभिव्यक्ति को एम्बेड करने की अनुमति देते हैं, जो तब स्वचालित रूप से पार्स और मूल्यांकन किए जाते हैं।

let actor = {name: 'RajiniKanth', age: 68};

let oldWayStr = "<p>My name is " + actor.name + ",</p>\n" +
  "<p>I am " + actor.age + " old</p>\n";

let newWayHtmlStr =
 `<p>My name is ${actor.name},</p>
  <p>I am ${actor.age} old</p>`;

console.log(oldWayStr);
console.log(newWayHtmlStr);

जैसा कि आप देख सकते हैं, हमने वर्णों की एक श्रृंखला के आसपास ..`` का उपयोग किया, जिन्हें एक स्ट्रिंग शाब्दिक के रूप में व्याख्या की जाती है, लेकिन प्रपत्र के किसी भी भाव को ${..}तुरंत इनलाइन किया जाता है और मूल्यांकन किया जाता है।

प्रक्षेपित स्ट्रिंग शाब्दिकों का एक बहुत अच्छा लाभ यह है कि उन्हें कई लाइनों में विभाजित करने की अनुमति दी जाती है:

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!

प्रक्षेपित भाव

किसी भी वैध अभिव्यक्ति को ${..}एक इंटरपोलेटेड स्ट्रिंग में प्रदर्शित करने की अनुमति है lit‐ eral, जिसमें फ़ंक्शन कॉल, इनलाइन फ़ंक्शन एक्सप्रेशन कॉल और अन्य भी शामिल हैं interpo‐ lated string literals!

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!

यहाँ, आंतरिक $ {who} s`` प्रक्षेपित स्ट्रिंग शाब्दिक हमारे लिए थोड़ा सा अच्छा सुविधा था जब "s"स्ट्रिंग के साथ कौन सा चर संयोजन किया गया था, जो कि + "s" के विपरीत था। एक नोट रखने के लिए भी एक प्रक्षेपित स्ट्रिंग शाब्दिक है lexically scopedजहाँ यह प्रकट होता है, dynamically scopedकिसी भी तरह से नहीं

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!"

template literalझुंझलाहट को कम करके HTML के लिए उपयोग करना निश्चित रूप से अधिक पठनीय है।

सादा पुराना तरीका:

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

के साथ ES6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
  • आपका तार कई पंक्तियों को फैला सकता है।
  • आपको उद्धरण वर्णों से बचने की आवश्यकता नहीं है।
  • आप समूहन से बच सकते हैं जैसे: ''> ''
  • आपको प्लस ऑपरेटर का उपयोग करने की आवश्यकता नहीं है।

टैग की गईं साक्षरता साहित्य

हम एक templateस्ट्रिंग को भी टैग कर सकते हैं , जब एक templateस्ट्रिंग को टैग किया जाता है, literalsऔर प्रतिस्थापन को कार्य करने के लिए पारित किया जाता है जो परिणामी मान लौटाता है।

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

हम spreadकई मान पास करने के लिए ऑपरेटर का उपयोग कर सकते हैं । पहला तर्क - हमने इसे स्ट्रिंग्स कहा - सभी सादे स्ट्रिंग्स (किसी भी प्रक्षेपित अभिव्यक्तियों के बीच सामान) की एक सरणी है।

इसके बाद हम सभी बाद के तर्कों को एक सरणी में इकट्ठा करते हैं, जिसका उपयोग मानों के रूप में किया जाता है ... gather/rest operator, हालांकि आप निश्चित रूप से उन्हें छोड़ सकते हैं जैसे कि ऊपर दिए गए स्ट्रिंग्स पैरामीटर के बाद व्यक्तिगत नामित पैरामीटर (value1, value2 etc)

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

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

argument(s)पहले से ही मूल्यांकन प्रक्षेप स्ट्रिंग शाब्दिक में पाया भाव के परिणाम हमारे मूल्यों सरणी में इकट्ठा कर रहे हैं। tagged string literalप्रक्षेपों के मूल्यांकन के बाद A एक प्रसंस्करण चरण की तरह है लेकिन अंतिम स्ट्रिंग मान संकलित करने से पहले, आपको शाब्दिक से स्ट्रिंग उत्पन्न करने पर अधिक नियंत्रण की अनुमति देता है। आइए, एक उदाहरण बनाते हैं re-usable templates

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);

कच्चे तार

हमारे टैग फ़ंक्शंस में एक पहला तर्क मिलता है जिसे हमने कॉल किया है strings, जो एक है array। लेकिन इसमें एक अतिरिक्त बिट डेटा शामिल है: सभी स्ट्रिंग्स के कच्चे असंसाधित संस्करण। आप .rawसंपत्ति का उपयोग करके उन कच्चे स्ट्रिंग मानों तक पहुँच सकते हैं, जैसे:

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

जैसा कि आप देख सकते हैं, rawस्ट्रिंग का संस्करण बच गए \ n अनुक्रम को संरक्षित करता है, जबकि स्ट्रिंग का संसाधित संस्करण इसे एक वास्तविक वास्तविक नई-रेखा की तरह मानता है। ES6एक अंतर्निहित फ़ंक्शन के साथ आता है जिसे स्ट्रिंग शाब्दिक टैग के रूप में उपयोग किया जा सकता है String.raw(..):। यह बस के कच्चे संस्करणों से गुजरता है strings:

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

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

4

यह बहुत साफ है और जैसा कि टिप्पणियों में कहा गया है, अन्य भाषाओं में एक सामान्य विशेषता है। दूसरी बात जो मुझे अच्छी लगी, वह थी स्ट्रिंग्स लिखते समय बहुत उपयोगी।

let person = {name: 'John Smith', age: 24, greeting: 'Cool!' };

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);

मुझे समझ में नहीं आता अगर एक स्ट्रिंग और शाब्दिक में लाइनब्रेक होने में एक बड़ा अंतर है। इस es6fiddle.net/i3vj1ldl की जाँच करें । शाब्दिक केवल एक पंक्ति विराम के बजाय एक स्थान रखता है
नईम शेख

1
वाह, मैंने नहीं कहा कि यह एक बड़ा अंतर था। शाब्दिक पंक्ति विराम सिंटैक्स चीनी हैं। यह सिर्फ पठनीयता के लिए है।
रिगोटी

लेकिन फिर भी आपने एक अच्छा अंतर बताया। लेकिन आपके उत्तर को स्वीकार करने से पहले, मैं एक बेहतर उत्तर के लिए कुछ और समय की प्रतीक्षा करूँगा जो किसी भी बड़े अंतर को दर्शाता है (यदि कोई है!) :)
नईम शेख

2
@NaeemShaikh मुझे बहुत खेद है, लेकिन शाब्दिक लाइन टूटती है वास्तव में काम करते हैं। बस ध्यान दिया कि ES6Fiddle यह परीक्षण करने के लिए सिर्फ एक भयानक तरीका है। मैं अपना उत्तर संपादित करूँगा।
रिगोटी

2

जबकि, मेरा उत्तर सीधे प्रश्न को संबोधित नहीं करता है। मैंने सोचा कि यह कुछ हित के लिए हो सकता है कि सरणी में शामिल होने के पक्ष में टेम्पलेट शाब्दिक का उपयोग करने के एक दोष को इंगित करें।

आइए हम कहते हैं

let patient1 = {firstName: "John", lastName: "Smith"};
let patient2 = {firstName: "Dwayne", lastName: "Johnson", middleName: "'The Rock'"};

तो कुछ रोगियों में एक मध्यनाम है और अन्य नहीं है।

अगर मुझे एक मरीज के पूरे नाम का प्रतिनिधित्व करने वाला एक स्ट्रिंग चाहिए

let patientName = `${patient1.firstName} ${patient1.middleName} ${patient1.lastName}`;

फिर यह "जॉन अपरिभाषित स्मिथ" बन जाएगा

हालांकि अगर मैंने किया

let patientName = [patient1.firstName, patient1.middleName,  patient1.lastName].join(" ");

फिर यह सिर्फ "जॉन स्मिथ" बन जाएगा

संपादित करें

General_Twyckenham ने बताया कि "" पर शामिल होने से "जॉन" और "स्मिथ" के बीच एक अतिरिक्त स्थान होगा।

इस के चारों ओर पाने के लिए आप नकली मूल्यों से छुटकारा पाने के लिए शामिल होने से पहले एक फ़िल्टर कर सकते हैं: [patient1.firstName, patient1.middleName, patient1.lastName].filter(el => el).join(" ");


2
वास्तव में, यह काफी सही नहीं है - joinसंस्करण आपको जॉन स्मिथ को एक अतिरिक्त स्थान देगा। जैसा कि आप कल्पना कर सकते हैं, यह अक्सर अवांछनीय है। इसके लिए एक फिक्स इस mapतरह का उपयोग करना है:[patient1.firstName, patient1.middleName, patient1.lastName].map(el => el).join(" ");
General_Twyckenham

@General_Twyckenham आह मैं आपकी बात देखता हूं। अच्छी पकड़। इसके अलावा, यह फिल्टर होना चाहिए और उस अतिरिक्त स्थान से छुटकारा पाने के लिए मानचित्र नहीं होना चाहिए। मैं अपना उत्तर संपादित करूंगा, धन्यवाद।
ध्रुव प्रकाश

वूप्स - हाँ, filterमैं समारोह का मतलब था।
General_Twyckenham

और इस चर्चा के अनुसार, स्ट्रिंग कॉन्फेटनेट सरणी जॉइन की तुलना में तेज है। stackoverflow.com/questions/7299010/…
माइकल हार्ले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.