skip to Main Content

Is it possible to interpolate a template string using key/values from a object in JavaScript, like string substitution in Python:

data = {"age": 18, "name": "John"}
"I'm %(name)s. I'm %(age)d years old" % data       # "I'm John. I'm 18 years old"

One way that I can think of is using the with statement,

let data = {age: 18, name: "John"}
with(data){`I'm ${name}. I'm ${age} years old`}

but with is highly not recommended, it is neither efficient nor safe.

Is there a better way?

2

Answers


  1. Chosen as BEST ANSWER

    I realized that there is a major difference between Python's string substitution and JavsScript's template string.

    • The template string in Python is exactly a string, it is only substituted when % is called,
    • while the template string in JS is substituted at the time it is declared and evaluated.

    So, the answer could be different in different scenarios:

    If I simply want to interpolate a template string with a specific object named data, I can simply use

    `I'm ${data.name}. I'm ${data.age} years old`
    

    If I want to declare a template string, and interpolate it using different objects, I can use a function:

    (_=>`I'm ${_.name}. I'm ${_.age} years old`)(data1)    // `data1` can also be `data2` or `person3`
    

    If I want to have some more elegent template strings, and make it somewhat programmable, I can use a tag function:

    function interpolate(strings, ...keys){
        return function(obj){
            let i
            let result=""
            for(i=0;i<keys.length;i++){
                result+=strings[i]+obj[keys[i]]
            }
            return result+strings[i]
        }
    }
    // or an inline version, some difference in `undefined` value handling:
    interpolate=(strings,...keys)=>(obj=>new Array(keys.length*2+1).fill().map((_,i)=>i&1?obj[keys[i>>1]]:strings[i>>1]).join(""))
    // usage
    interpolate`I'm ${"name"}. I'm ${"age"} years old.`(data)
    

  2. You can destruct data object:

    let data = {age: 18, name: "John"}
    function with({name,age}){ return `I'm ${name}. I'm ${age} years old`; }
    

    or do this:

    let data = {age: 18, name: "John"}
    function with(data){return `I'm ${data.name}. I'm ${data.age} years old`;}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search