2016-12-13 19 views
12

Say mam zmienną strinterpolacja String o zmiennej

var str = "123" 

Teraz mogę zrobić console.log(`Hello ${str}`) i będzie drukować Hello 123

Teraz mam inną zmienną strnew

var strnew = 'Hello ${str}' 

Note (w oparciu na odpowiedzi/komentarze) - strnew jest czytany z pliku, więc zawsze jest ciągiem i nie może być zastąpione `

Jak console.log(...) wydrukować Hello 123

Czy możliwe wihtout jakiejkolwiek eval()

+2

prawdopodobnie związane: http://stackoverflow.com/q/40235363/476 – deceze

+1

Myślę, że najlepszym sposobem, w tym przypadku jest użycie funkcji, które akceptuje 'str' i wykorzystuje ten ciąg wewnątrz szablonu. –

+0

Myślę, że to tylko przykład, jeśli masz bardzo długi ciąg z wieloma konkatenacjami - ciąg szablonów jest lepszy. –

Odpowiedz

17

Z czegoś tak prostego jak ${str} można użyć prostego zastąpienia wyrażenie:

var template = (tpl, args) => tpl.replace(/\${(\w+)}/g, (_, v) => args[v]); 
 

 
var tpl = 'Hello ${str} and ${other}'; 
 

 
console.log(template(tpl, {str: 'foo', other: 'bar'}));

W ogólnym przypadku, nie, nie jest możliwe bez eval (brak pisania własnego tłumacza), ponieważ ${...} może zawierać dowolne wyrażenia.

kompletności boską, oto rozwiązanie eval:

var template = function(tpl, args) { 
 
    var keys = Object.keys(args), 
 
     fn = new Function(...keys, 
 
      'return `' + tpl.replace(/`/g, '\\`') + '`'); 
 
    return fn(...keys.map(x => args[x])); 
 
}; 
 

 

 
function test() { 
 
    var myTpl = 'Hello ${str + "!"} and ${other.toUpperCase()}'; 
 
    console.log(template(myTpl, {str: 'foo', other: 'bar'})); 
 
} 
 

 
test();

+0

Bardzo mi przykro, zredagowałem Twój post zamiast sugerować zmianę, ale ja to cofnąłem. nowa funkcja ('', 'return '' + tpl + '''); może być zoptymalizowany do nowej funkcji ("return" + tpl + "' "); – lustoykov

+0

@leo: możesz edytować, tak działa SO;) – georg

+0

Świetna odpowiedź !! To powinna być zaakceptowana odpowiedź. Daj mi dzień lub dwa, żeby to potwierdzić. –

1

Można użyć funkcji zamiast tylko ciąg.

var strnew = function(str){ 
 
    return `Hello ${str}`; 
 
} 
 
var str = "123"; 
 
console.log(strnew(str))

+2

IMHO to najlepsze rozwiązanie i prawdopodobnie sposób, w jaki literały szablonowe miały być używane. – nils

+0

Ciągi szablonów są odczytywane z pliku, nie znajdują się w kodzie OP. – georg

+0

@georg tak, dodał tę notatkę później, napisałem komentarz na ten temat. –

0

Dzięki this answer, tutaj jest trochę czarnej magii kodu, który osiąga co chcesz. Zastrzeżenie - jest to dla zabawy/bardzo ograniczone i egzotyczne zastosowanie. Prawdopodobnie będzie bardzo powolny i ulegnie awarii w wielu skrajnych przypadkach, ale przy ograniczonym zakresie twojego pytania zadziała.

function getString(){ 
 
\t return "calculating ${foo} + ${bar} = ${foo + bar}"; 
 
} 
 

 
var localEnvironmentProxy = new Proxy({}, { 
 
    has(target, prop) { return true; }, 
 
    get(target, prop) { return (prop in target ? target : window)[prop]; } 
 
    }); 
 
    
 
    with(localEnvironmentProxy){ 
 
    
 
\t var foo = 1; 
 
\t var bar = 2; 
 
    
 
\t var templString = getString(); 
 
\t 
 
\t var fnFullText = 'with(arguments[0]){ return `' + templString + '`;}'; 
 
\t 
 
\t var tempalteFn = new Function(fnFullText); 
 
\t \t \t \t 
 
\t console.log(tempalteFn(localEnvironmentProxy)); 
 
    //calculating 1 + 2 = 3 
 
    
 
    }