pasaba por aqui
pasaba por aqui

Reputation: 3519

javascript nested template strings

In javascript, assume some data definitions similar to these ones:

y='${z}' 
z='hi' // y and z can be constants, or read from file, or ...
x=`===${y}===`

Is it possible to write a "simple" javascript code that finishes with "x" being equal to "===hi===" instead of "===${z}===" ?

( note the steps to find the target result are "===${y}===" => "===${z}===" => "===hi===" ).

That is, could behavior of template strings (replacement of ${k} by k value) be used in a "loop" until no more ${} to replace in the resulting string ?

Better if the solution allows data be stored in a map instead of in the current context. That is, starting from

data = { x : '===${y}===', y: '${y}', z='hi' }

the call:

myFunction(data, 'x') 

should return '===hi==='.

Upvotes: 0

Views: 682

Answers (1)

Esc Điệp
Esc Điệp

Reputation: 356

It is possible by using eval.
Below code show the way to do this job in global context.

x = '===${y}===';
y = '${z}';
z = 'hi';

template = x;
result = x;
do {
    template = result;
    result = eval("`"+template+"`");
} while(result != template);
result;

In non global context, you can create a function as a string and pass to the eval function. Below code show how to do this.

let data = { x : '===${y}===', y: '${z}', z : 'hi' }
let myFunction = function(data, member) {
    let env = ["(function() { \n"];
    for(let prop in data){
        env.push("\tlet ");
        env.push(prop);
        env.push(" = '");
        env.push(data[prop]);
        env.push("';\n");
    }
    let template = data[member]
    let result  = data[member];
    do {
        template = result;
        env.push("\treturn `"+template+"`;\n");
        env.push("})();");
        result = eval(env.join(""));
        env.pop();
        env.pop();
    } while(result!=template);

    return result;
}
myFunction(data, "x");

Upvotes: 1

Related Questions