2017-09-26 148 views
1

在Python中,你可以做可變字符串插值像這樣:將JS對象作爲範圍傳遞給JS模板文字?

song_context = { "adjective": "funny" } 
ella_sings = "my {adjective} valentine".format(**song_context) 

這裏,song_context對象格式變量在ella_sings字符串。

在ES6中是否有內置的方法可以使用模板文字來做類似的事情?我正在尋找一種快速的方法來明確定義給定字符串的替代空間。例如:

const song_context = { adjective: "funny" } 
const ella_sings = `my ${adjective} valentine`.format(song_context) 

上下文:我知道其他方法可以做到這一點,例如,使用a template library或者做multiple find and replace,但是我想知道ES6的任何部分是否支持這個開箱即用的用例。我撇去了template literal part of the ECMAScript 6.0 standard,它很清楚地說明了"Let ctx be the running execution context",但它似乎很難相信他們不會提供一種方式,以便在必要時更清楚地瞭解關於上下文的更多

+0

爲什麼你要在一個對象中使用字符串文字來形容詞? –

+1

模板文字不是實際模板引擎的替代品。 –

+0

@RobertMennell這就是問題 - 我想將對象傳遞給模板文字,而不是使用模板文字的上下文。 –

回答

0

你可能想通過在Javascript MDN讀了一下更多關於它們並注意稱爲標籤模板文字的部分,因爲它展示瞭如何把文字變成一個完整的模板的模板。

備案我要導入相關的部分:

標籤模板文字

模板文字的更高級形式的標籤模板文字。標籤允許您使用函數解析模板文字。標記函數的第一個參數包含一個字符串值數組。其餘的參數與表達式有關。最後,你的函數可以返回你的操縱字符串(或者它可以返回與下一個例子中描述的完全不同的東西)。用於標籤的函數名稱可以任意命名。

var person = 'Mike'; 
var age = 28; 

function myTag(strings, personExp, ageExp) { 

    var str0 = strings[0]; // "that " 
    var str1 = strings[1]; // " is a " 

    // There is technically a string after 
    // the final expression (in our example), 
    // but it is empty (""), so disregard. 
    // var str2 = strings[2]; 

    var ageStr; 
    if (ageExp > 99){ 
    ageStr = 'centenarian'; 
    } else { 
    ageStr = 'youngster'; 
    } 

    return str0 + personExp + str1 + ageStr; 

} 

var output = myTag`that ${ person } is a ${ age }`; 

console.log(output); 
// that Mike is a youngster 

標記函數不需要返回一個字符串,如下例所示。

function template(strings, ...keys) { 
    return (function(...values) { 
    var dict = values[values.length - 1] || {}; 
    var result = [strings[0]]; 
    keys.forEach(function(key, i) { 
     var value = Number.isInteger(key) ? values[key] : dict[key]; 
     result.push(value, strings[i + 1]); 
    }); 
    return result.join(''); 
    }); 
} 

var t1Closure = template`${0}${1}${0}!`; 
t1Closure('Y', 'A'); // "YAY!" 
var t2Closure = template`${0} ${'foo'}!`; 
t2Closure('Hello', {foo: 'World'}); // "Hello World!" 

這些標記的模板字面值似乎正是你想要的。

0

您可以創建一個函數來編譯模板,然後接受上下文作爲其參數。唯一的問題是你需要在花括號內放置引號。

const compileTemplate = (template, ...replacements) => 
    ctx => 
     template.reduce(
      (accumulator, part, i) => 
       accumulator + ctx[replacements[i - 1]] + part 

      ); 


const templateFn = compileTemplate`This is a ${'adj'} problem.`; 

console.log(templateFn({adj: 'hard'})); 
console.log(templateFn({adj: 'funny'})); 
3

在ES6是有一個內置的方式做這樣的事情與模板的文字?

模板文字沒有特別的邏輯。 ${..}括號之間的代碼只是一個正常表達式,可以將其評估爲一個值。

`my ${adjective} valentine` 

總是要去尋找一個在局部範圍命名爲adjective變量。你當然可以改變它做

`my ${song_context.adjective} valentine` 

如果你不想改變它的一部分,那麼你可以隨時使用解構,如

const {adjective} = song_context; 
const ella_sings = `my ${adjective} valentine` 

或使用IIFE:

const ella_sings = ({adjective}) => `my ${adjective} valentine`)(song_context); 

,如果你願意,你也可以建立一個圍繞模板文字你自己的模板系統,但它開始變得複雜,速度快,失去大部分,使你想的好處首先使用模板文字。

相關問題