【问题标题】:How to interpolate variables in strings in JavaScript, without concatenation?如何在不连接的情况下在 JavaScript 中的字符串中插入变量?
【发布时间】:2011-03-19 06:07:59
【问题描述】:

我知道在 PHP 中我们可以这样做:

$hello = "foo";
$my_string = "I pity the $hello";

输出:"I pity the foo"

我想知道在 JavaScript 中是否也可以实现同样的事情。在字符串中使用变量而不使用连接 — 写起来更简洁优雅。

【问题讨论】:

    标签: javascript string variables string-interpolation


    【解决方案1】:

    您可以利用Template Literals 并使用以下语法:

    `String text ${expression}`
    

    模板文字用 反引号 (` `)(重音符号)而不是双引号或单引号括起来。

    此功能已在 ES2015 (ES6) 中引入。

    示例

    var a = 5;
    var b = 10;
    console.log(`Fifteen is ${a + b}.`);
    // "Fifteen is 15.
    

    这有多整洁?

    奖金:

    它还允许在 javascript 中使用多行字符串而无需转义,这对于模板来说非常有用:

    return `
        <div class="${foo}">
             ...
        </div>
    `;
    

    Browser support:

    由于旧浏览器(主要是 Internet Explorer)不支持此语法,您可能需要使用 Babel/Webpack 将代码转换为 ES5 以确保它可以在任何地方运行。


    旁注:

    从 IE8+ 开始,您可以在 console.log 中使用基本的字符串格式:

    console.log('%s is %d.', 'Fifteen', 15);
    // Fifteen is 15.
    

    【讨论】:

    • 不要错过模板字符串用反引号 (`) 而不是正常的引号字符分隔的事实。 "${foo}" 实际上是 ${foo} `${foo}` 是你真正想要的
    • 还有很多转译器可以把 ES6 转成 ES5 来修复兼容性问题!
    • 当我更改 a 或 b 值时。控制台.log(Fifteen is ${a + b}.);不会动态改变。它总是显示 15 是 15。
    • 倒勾是救命稻草。
    • 但问题是当我在 php 文件中使用它时,$variable 将被视为 php 变量而不是 js 变量,因为 php 变量的格式为 $variable_name。
    【解决方案2】:

    Prior to Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge,不,这在 javascript 中是不可能的。您将不得不求助于:

    var hello = "foo";
    var my_string = "I pity the " + hello;
    

    【讨论】:

    • 很快就会在带有模板字符串的 javascript (ES6) 中实现,请参阅下面的详细答案。
    • It is possible 如果你喜欢写 CoffeeScript,它实际上是语法更好的 javascript。
    • 老版本浏览器的大呼:)
    【解决方案3】:

    Prior to Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge,没有。虽然你可以尝试sprintf for JavaScript 来达到一半:

    var hello = "foo";
    var my_string = sprintf("I pity the %s", hello);
    

    【讨论】:

    【解决方案4】:

    你可以这样做,但它不是一般的

    'I pity the $fool'.replace('$fool', 'fool')
    

    如果您真的需要,您可以轻松编写一个智能地执行此操作的函数

    【讨论】:

    • 相当不错,实际上。
    • 当您需要将模板字符串存储在数据库中并按需处理时,这个答案很好
    • 不错,效果很好。很简单,但没想到。
    【解决方案5】:

    完整答案,可以使用:

     var Strings = {
            create : (function() {
                    var regexp = /{([^{]+)}/g;
    
                    return function(str, o) {
                         return str.replace(regexp, function(ignore, key){
                               return (key = o[key]) == null ? '' : key;
                         });
                    }
            })()
    };
    

    调用

    Strings.create("My firstname is {first}, my last name is {last}", {first:'Neo', last:'Andersson'});
    

    将其附加到 String.prototype:

    String.prototype.create = function(o) {
               return Strings.create(this, o);
    }
    

    然后用作:

    "My firstname is ${first}".create({first:'Neo'});
    

    【讨论】:

      【解决方案6】:

      你可以使用这个 javascript 函数来做这种模板。无需包含整个库。

      function createStringFromTemplate(template, variables) {
          return template.replace(new RegExp("\{([^\{]+)\}", "g"), function(_unused, varName){
              return variables[varName];
          });
      }
      
      createStringFromTemplate(
          "I would like to receive email updates from {list_name} {var1} {var2} {var3}.",
          {
              list_name : "this store",
              var1      : "FOO",
              var2      : "BAR",
              var3      : "BAZ"
          }
      );
      

      输出"I would like to receive email updates from this store FOO BAR BAZ."

      使用函数作为 String.replace() 函数的参数是 ECMAScript v3 规范的一部分。详情请见this SO answer

      【讨论】:

      • 这样有效率吗?
      • 效率很大程度上取决于用户的浏览器,因为该解决方案将匹配正则表达式和进行字符串替换的“繁重工作”委托给浏览器的本机功能。无论如何,由于这无论如何都发生在浏览器端,因此效率并不是一个大问题。如果您想要服务器端模板(用于 Node.JS 等),您应该使用@bformet 描述的 ES6 模板文字解决方案,因为它可能更有效。
      【解决方案7】:

      如果你喜欢编写 CoffeeScript,你可以这样做:

      hello = "foo"
      my_string = "I pity the #{hello}"
      

      CoffeeScript 实际上是 javascript,但语法要好得多。

      有关 CoffeeScript 的概述,请查看beginner's guide

      【讨论】:

        【解决方案8】:

        我会使用反引号``。

        let name1 = 'Geoffrey';
        let msg1 = `Hello ${name1}`;
        console.log(msg1); // 'Hello Geoffrey'
        

        但是如果你在创建msg1时不知道name1

        例如,如果 msg1 来自 API。

        你可以使用:

        let name2 = 'Geoffrey';
        let msg2 = 'Hello ${name2}';
        console.log(msg2); // 'Hello ${name2}'
        
        const regexp = /\${([^{]+)}/g;
        let result = msg2.replace(regexp, function(ignore, key){
            return eval(key);
        });
        console.log(result); // 'Hello Geoffrey'
        

        它将用他的值替换${name2}

        【讨论】:

          【解决方案9】:

          我编写了这个 npm 包 stringinject https://www.npmjs.com/package/stringinject,它允许您执行以下操作

          var string = stringInject("this is a {0} string for {1}", ["test", "stringInject"]);
          

          这会将 {0} 和 {1} 替换为数组项并返回以下字符串

          "this is a test string for stringInject"
          

          或者您可以使用对象键和值替换占位符,如下所示:

          var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });
          
          "My username is tjcafferkey on Github" 
          

          【讨论】:

            【解决方案10】:

            如果您尝试为微模板进行插值,我喜欢 Mustache.js

            【讨论】:

              【解决方案11】:

              这里没有提到任何外部库,但 Lodash 有 _.template()

              https://lodash.com/docs/4.17.10#template

              如果您已经在使用该库,那么值得一试,如果您没有使用 Lodash,您可以随时从 npm npm install lodash.template 中挑选方法,这样您就可以减少开销。

              最简单的形式 -

              var compiled = _.template('hello <%= user %>!');
              compiled({ 'user': 'fred' });
              // => 'hello fred!'
              

              还有很多配置选项-

              _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
              var compiled = _.template('hello {{ user }}!');
              compiled({ 'user': 'mustache' });
              // => 'hello mustache!'
              

              我发现自定义分隔符最有趣。

              【讨论】:

                【解决方案12】:

                简单使用:

                var util = require('util');
                
                var value = 15;
                var s = util.format("The variable value is: %s", value)
                

                【讨论】:

                  【解决方案13】:
                  String.prototype.interpole = function () {
                      var c=0, txt=this;
                      while (txt.search(/{var}/g) > 0){
                          txt = txt.replace(/{var}/, arguments[c]);
                          c++;
                      }
                      return txt;
                  }
                  

                  我们:

                  var hello = "foo";
                  var my_string = "I pity the {var}".interpole(hello);
                  //resultado "I pity the foo"
                  

                  【讨论】:

                    【解决方案14】:

                    创建一个类似于Java的String.format()的方法

                    StringJoin=(s, r=[])=>{
                      r.map((v,i)=>{
                        s = s.replace('%'+(i+1),v)
                      })
                    return s
                    }
                    

                    使用

                    console.log(StringJoin('I can %1 a %2',['create','method'])) //output: 'I can create a method'
                    

                    【讨论】:

                      【解决方案15】:

                      2020 年和平行情:

                      Console.WriteLine("I {0} JavaScript!", ">:D<");
                      
                      console.log(`I ${'>:D<'} C#`)
                      

                      【讨论】:

                        【解决方案16】:

                        var hello = "foo";

                        var my_string ="I pity the";
                        

                        console.log(my_string, 你好)

                        【讨论】:

                        • 这不能回答问题。您可以在一行中注销两个字符串,但这不会为您提供包含两个字符串的新字符串,这是 OP 所要求的。
                        猜你喜欢
                        • 2012-06-25
                        • 1970-01-01
                        • 2021-05-16
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2013-11-10
                        相关资源
                        最近更新 更多