0

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==='.

9
  • When you say "recursive", can you show an example of this? How should a string like ===${${y}y}=== be interpreted? Commented Jun 14, 2019 at 15:38
  • If you set y='${z}' to y=`${z}`, it is ok. Print x and it will print the expected result. Commented Jun 14, 2019 at 15:41
  • @ggorlen: if necessary, we can assume that inside ${} only a valid js identifier will be present. however, the best sequence for the case you present is ===${${y}y}=== -> ===${${z}y}=== -> ===${hiy}=== -> ====== Commented Jun 14, 2019 at 15:43
  • @sjahan: I know, I will clarify the question. Commented Jun 14, 2019 at 15:44
  • About having everything in the same object, I doubt you can do it without making something fishy. Commented Jun 14, 2019 at 15:45

1 Answer 1

1

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");
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.