如何在JavaScript中进行字符串插值?

时间:2009-09-10 23:40:11

标签: javascript string string-interpolation

考虑以下代码:

var age = 3;

console.log("I'm " + age + " years old!");

除了字符串连接之外,还有其他方法可以将变量的值插入字符串吗?

22 个答案:

答案 0 :(得分:349)

从ES6开始,您可以使用template literals



let age = 3
console.log(`I'm ${age} years old!`)




P.S。请注意使用反引号:``

答案 1 :(得分:219)

TL;博士

使用ECMAScript 2015的模板字符串文字(如果适用)。

说明

根据ECMAScript 5规范,没有直接的方法可以做到这一点,但ECMAScript 6有template strings,在规范的起草过程中也被称为quasi-literals。像这样使用它们:

> var n = 42;
undefined
> `foo${n}bar`
'foo42bar'

您可以在{}中使用任何有效的JavaScript表达式。例如:

> `foo${{name: 'Google'}.name}bar`
'fooGooglebar'
> `foo${1 + 3}bar`
'foo4bar'

另一个重要的事情是,您不必再担心多行字符串了。您可以将它们简单地写为

> `foo
...     bar`
'foo\n    bar'

注意:我使用io.js v2.4.0来评估上面显示的所有模板字符串。您还可以使用最新的Chrome来测试上面显示的示例。

注意: ES6规格为now finalized,但尚未由所有主流浏览器实施。
根据Mozilla Developer Network pages,这将从以下版本开始实施基本支持:Firefox 34,Chrome 41,Internet Explorer 12.如果您是Opera,Safari或Internet Explorer用户,现在很好奇,this test bed可以用来玩,直到每个人都得到支持。

答案 2 :(得分:185)

道格拉斯·克罗克福德的Remedial JavaScript包括String.prototype.supplant函数。它简短,熟悉且易于使用:

String.prototype.supplant = function (o) {
    return this.replace(/{([^{}]*)}/g,
        function (a, b) {
            var r = o[b];
            return typeof r === 'string' || typeof r === 'number' ? r : a;
        }
    );
};

// Usage:
alert("I'm {age} years old!".supplant({ age: 29 }));
alert("The {a} says {n}, {n}, {n}!".supplant({ a: 'cow', n: 'moo' }));

如果您不想更改String的原型,您可以随时将其调整为独立的,或将其放入其他名称空间或其他任何名称。

答案 3 :(得分:49)

提醒:避免任何不允许您逃避自己的分隔符的模板系统。例如,使用此处提到的supplant()方法无法输出以下内容。

  

“感谢我的{age}变量,我已经3岁了。”

简单插值可能适用于小型自包含脚本,但通常会出现这种设计缺陷,限制任何严重的使用。老实说,我更喜欢DOM模板,例如:

<div> I am <span id="age"></span> years old!</div>

并使用jQuery操作:$('#age').text(3)

或者,如果您只是厌倦了字符串连接,那么总会有替代语法:

var age = 3;
var str = ["I'm only", age, "years old"].join(" ");

答案 4 :(得分:22)

试试sprintf。例如:

vsprintf('The first 4 letters of the english alphabet are: %s, %s, %s and %s', ['a', 'b', 'c', 'd']);

答案 5 :(得分:21)

如果你真的想用大锤来破解坚果,你可以使用Prototype's template system

var template = new Template("I'm #{age} years old!");
alert(template.evaluate({age: 21}));

答案 6 :(得分:15)

当我不知道如何正确地使用这种模式时,我会在很多语言中使用这种模式而只是想快速得到一个想法:

// JavaScript
var stringValue = 'Hello, my name is {name}. You {action} my {relation}.'
    .replace(/{name}/g    ,'Indigo Montoya')
    .replace(/{action}/g  ,'killed')
    .replace(/{relation}/g,'father')
    ;

虽然不是特别有效,但我发现它可读。它始终有效,并始终可用:

' VBScript
dim template = "Hello, my name is {name}. You {action} my {relation}."
dim stringvalue = template
stringValue = replace(stringvalue, "{name}"    ,"Luke Skywalker")     
stringValue = replace(stringvalue, "{relation}","Father")     
stringValue = replace(stringvalue, "{action}"  ,"are")

始终

* COBOL
INSPECT stringvalue REPLACING FIRST '{name}'     BY 'Grendel'
INSPECT stringvalue REPLACING FIRST '{relation}' BY 'Mother'
INSPECT stringvalue REPLACING FIRST '{action}'   BY 'did unspeakable things to'

答案 7 :(得分:9)

您可以轻松地使用ES6 template string并使用任何可用的传播方式(如babel)转换到ES5。

const age = 3;

console.log(`I'm ${age} years old!`);

http://www.es6fiddle.net/im3c3euc/

答案 8 :(得分:6)

这是一个需要您为对象提供值的解决方案。如果您未提供对象作为参数,则默认使用全局变量。但最好坚持使用参数,它更清洁。

&#13;
&#13;
String.prototype.interpolate = function(props) {
    return this.replace(/\{(\w+)\}/g, function(match, expr) {
        return (props || window)[expr];
    });
};

// Test:

// Using the parameter (advised approach)
document.getElementById("resultA").innerText = "Eruption 1: {eruption1}".interpolate({ eruption1: 112 });

// Using the global scope
var eruption2 = 116;
document.getElementById("resultB").innerText = "Eruption 2: {eruption2}".interpolate();
&#13;
<div id="resultA"></div><div id="resultB"></div>
&#13;
&#13;
&#13;

答案 9 :(得分:6)

尝试使用kiwi轻量级JavaScript模块进行字符串插值。

你可以做到

Kiwi.compose("I'm % years old!", [age]);

Kiwi.compose("I'm %{age} years old!", {"age" : age});

答案 10 :(得分:5)

使用`grave accents also known as backtick)代替单引号(')或双引号(")和美元符号/括号${ variable } < / p>

例如:

console.log(
  `current date: ${new Date()}`
);

详细了解模板文字here

答案 11 :(得分:4)

如果要在console.log输出中进行插值,则只需

console.log("Eruption 1: %s", eruption1);
                         ^^

这里,%s是所谓的“格式说明符”。 console.log内置了这种插值支持。

答案 12 :(得分:2)

扩展Greg Kindel's第二个答案,你可以编写一个函数来消除一些样板:

var fmt = {
    join: function() {
        return Array.prototype.slice.call(arguments).join(' ');
    },
    log: function() {
        console.log(this.join(...arguments));
    }
}

用法:

var age = 7;
var years = 5;
var sentence = fmt.join('I am now', age, 'years old!');
fmt.log('In', years, 'years I will be', age + years, 'years old!');

答案 13 :(得分:1)

我可以给你看一个例子:

function fullName(first, last) {
  let fullName = first + " " + last;
  return fullName;
}

function fullNameStringInterpolation(first, last) {
  let fullName = `${first} ${last}`;
  return fullName;
}

console.log('Old School: ' + fullName('Carlos', 'Gutierrez'));

console.log('New School: ' + fullNameStringInterpolation('Carlos', 'Gutierrez'));

答案 14 :(得分:1)

从ES6开始,如果要在对象键中进行字符串插值,则执行以下操作将得到SyntaxError: expected property name, got '${'

let age = 3
let obj = { `${age}`: 3 }

您应该改为执行以下操作:

let obj = { [`${age}`]: 3 }

答案 15 :(得分:1)

找不到我想要的东西,然后找到了-

如果您使用的是Node.js,则有一个内置util软件包,其格式函数如下所示:

util.format("Hello my name is %s", "Brent");
> Hello my name is Brent

巧合的是,Node.js现在也将其内置到console.log风格中-

console.log("This really bad error happened: %s", "ReferenceError");
> This really bad error happened: ReferenceError

答案 16 :(得分:1)

最简单的是

`my string ${VARIABLE}`

实现这一目标的效率较低的方法是

function format(str, ...params) {
  for(const param of params)
    str = str.replace("%", param);
   return str;
}

可以与

一起使用
format("My % string", "interpolation")

答案 17 :(得分:0)

在较旧的浏览器中,使用模板语法失败,如果要创建供公众使用的HTML,则很重要。使用级联非常繁琐且难以阅读,特别是在表达式很多或很长的情况下,或者必须使用括号来处理数字和字符串项的混合(两者都使用+运算符)时。

PHP使用非常紧凑的表示法来扩展包含变量甚至某些表达式的带引号的字符串:$a="the color is $color";

在JavaScript中,可以使用可变数量的参数编写高效的函数来支持此功能:var a=S('the color is ',color);。尽管在此示例中没有比串联的优势,但是当表达式变长时,此语法可能会更清晰。或者,可以像PHP中一样,使用JavaScript函数使用美元符号来表示表达式的开始。

另一方面,编写高效的解决方法功能来为较旧的浏览器提供类似于模板的字符串扩展并不难。可能已经有人做过。

最后,我认为sprintf(在C,C ++和PHP中)可以用JavaScript编写,尽管它的效率要比其他解决方案低。

答案 18 :(得分:0)

  

为@Chris Nielsen帖子的 ES6 版本替换更多内容。

matplotlib.pyplot.show()

答案 19 :(得分:0)

自定义灵活插值:

var jhon="michel";
var test=jhon +"\"+ "robert";

alert(test)
var sourceElm = document.querySelector('input')

// interpolation callback
const onInterpolate = s => `<mark>${s}</mark>`

// listen to "input" event
sourceElm.addEventListener('input', parseInput) 

// parse on window load
parseInput() 

// input element parser
function parseInput(){
  var html = interpolate(sourceElm.value, undefined, onInterpolate)
  sourceElm.nextElementSibling.innerHTML = html;
}

// the actual interpolation 
function interpolate(str, interpolator = ["{{", "}}"], cb){
  // split by "start" pattern
  return str.split(interpolator[0]).map((s1, i) => {
    // first item can be safely ignored
	  if( i == 0 ) return s1;
    // for each splited part, split again by "end" pattern 
    const s2 = s1.split(interpolator[1]);

    // is there's no "closing" match to this part, rebuild it
    if( s1 == s2[0]) return interpolator[0] + s2[0]
    // if this split's result as multiple items' array, it means the first item is between the patterns
    if( s2.length > 1 ){
        s2[0] = s2[0] 
          ? cb(s2[0]) // replace the array item with whatever
          : interpolator.join('') // nothing was between the interpolation pattern
    }

    return s2.join('') // merge splited array (part2)
  }).join('') // merge everything 
}
input{ 
  padding:5px; 
  width: 100%; 
  box-sizing: border-box;
  margin-bottom: 20px;
}

*{
  font: 14px Arial;
  padding:5px;
}

答案 20 :(得分:0)

虽然模板可能最适合您描述的情况,但是如果您具有或想要以可迭代/数组形式的数据和/或参数,则可以使用https://docs.solace.com/Solace-SW-Broker-Upgrade/AWS-Upgrade.htm

String.raw({
  raw: ["I'm ", " years old!"]
}, 3);

将数据作为数组,可以使用扩展运算符:

const args = [3, 'yesterday'];
String.raw({
  raw: ["I'm ", " years old as of ", ""]
}, ...args);

答案 21 :(得分:-1)

let age = 3;

console.log(`I'm ${age} years old!`);

您可以使用反引号``ES6模板字符串