Reputation: 3519
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
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