【问题标题】:How would you turn a JavaScript variable into a Template literal?如何将 JavaScript 变量转换为模板文字?
【发布时间】:2019-12-25 04:59:17
【问题描述】:

我想获取我生成并存储在字符串中的文本,并将其用作模板文字。

var generatedText = "Pretend this text was generated and then stored in a variable. "; 
generatedText = "But I still need to use it as a template it to get ${variable}.";

var variable = "Successs!!!!";

console.log(generatedText);
//prints 'But I still need to interpolate it to get ${variable}.'
//how can I make it print using variable in it like a template as if it were doing this
console.log(`But I still need to use it as a template it to get ${variable}.`);
//prints 'But I still need to use it as a template it to get Successs!!!!.'

如何让生成的文本成为模板字符串?

generatedText 必须以变量开头,所以如果可能,我需要找到一种方法将其转换为模板字符串。

编辑:

我不认为我必须提出这个,但我也不想使用 eval 来冒险评估随机代码......

【问题讨论】:

  • 为什么不直接使用模板文字而不是先保存为字符串然后尝试作为模板文字?你想达到什么目标?
  • 不清楚你在问什么。
  • @MeirKeller cmets 不是用来回答的。如果您认为自己的答案很好,请将其作为答案发布。
  • 重新打开,因为副本的前几个答案都没有CertainPerformance的好。有一些接近底部的,但这里似乎也不需要嵌套属性。

标签: javascript string template-literals


【解决方案1】:

对于一般情况,您可以使用替换函数将每次出现的${someProp} 替换为对象上的someProp 属性:

const interpolate = (str, obj) => str.replace(
  /\${([^}]+)}/g,
  (_, prop) => obj[prop]
);

const generatedText = "But I still need to use it as a template it to get ${variable}.";
const variable = "Successs!!!!";

console.log(interpolate(generatedText, { variable }));

正则表达式\${([^}]+)}表示:

  • \$ - 文字 $
  • { - 文字 {
  • ([^}]+) 第一个(也是唯一的)捕获组:
    • [^}]+ - 一个或多个不是} 的字符
  • } - 文字 }

由于prop 是括号之间的属性名称,因此替换为obj[prop] 以替换为所需的替换。

【讨论】:

  • 如何扩展您的解决方案以在 ${obj.foo.bar} 上工作?
  • 参见stackoverflow.com/q/6491463 - 使用reduce 遍历.s 之间的子字符串以获取嵌套值
【解决方案2】:

下面的interpolate 函数是this answer 的扩展版本,增加了对简单嵌套对象字段引用的支持(例如:a.b.c

function interpolate(s, obj) {
  return s.replace(/[$]{([^}]+)}/g, function(_, path) {
    const properties = path.split('.');
    return properties.reduce((prev, curr) => prev && prev[curr], obj);
  })
}

console.log(interpolate('hello ${a.b.c}', {a: {b: {c: 'world'}}}));
// Displays 'hello world'

【讨论】:

    【解决方案3】:

    您应该改为模拟模板文字,因为让来自 ~somewhere~ 的文本像真正的模板文字的 ${} 部分一样运行任意 JavaScript 通常不是一个好主意:

    generatedText.replace(/\$\{variable}/g, variable);
    

    【讨论】:

    • 某些性能答案更符合我的需求,因为我可以一次替换不同变量的多个实例,但这个答案也是正确的,符合我的要求并且不使用 eval。
    【解决方案4】:

    下面的插值函数是上述解决方案的扩展版本,增加了对简单嵌套对象字段引用的支持,并添加了数组(例如:a[0][2].b.c)

    const interpolate = (str, obj) => {
      return str.replace(/\${([^}]+)}/g, (_, target) => {
        let keys = target.split(".");
        return keys.reduce((prev, curr) => {
          if (curr.search(/\[/g) > -1) {
            //if element/key in target array is array, get the value and return
            let m_curr = curr.replace(/\]/g, "");
            let arr = m_curr.split("[");
            return arr.reduce((pr, cu) => {
              return pr && pr[cu];
            }, prev);
          } else {
            //else it is a object, get the value and return
            return prev && prev[curr];
          }
        }, obj);
      });
    };
    
    let template = "hello ${a[0][0].b.c}";
    let data = {
      a: [
        [{
          b: {
            c: "world",
            f: "greetings"
          }
        }, 2], 3
      ],
      d: 12,
      e: 14
    }
    console.log(interpolate(template, { ...data
    }));

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 2021-11-09
      • 2013-10-13
      • 2016-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多