考虑下面的代码:

var age = 3;

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

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


当前回答

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

“多亏了我的年龄变量,我才3岁。”

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

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

$('#age').text(3)

另外,如果你只是厌倦了字符串连接,总有替代语法:

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

其他回答

下面是一个解决方案,它要求您提供一个具有值的对象。如果你不提供一个对象作为参数,它将默认使用全局变量。但是最好还是使用参数,这样更简洁。

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(); <div id="resultA"></div><div id="resultB"></div>

你可以使用Prototype的模板系统,如果你真的想用大锤敲开一个坚果:

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

博士tl;

使用ECMAScript 2015的模板字符串字面量,如果适用。

解释

根据ECMAScript 5规范,没有直接的方法来做到这一点,但ECMAScript 6有模板字符串,在规范起草期间也被称为准字面量。像这样使用它们:

> 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规范现在已经最终确定,但还没有被所有主要浏览器实现。根据Mozilla开发者网络页面,这将从以下版本开始实现基本支持:Firefox 34, Chrome 41, Internet Explorer 12。如果您是Opera、Safari或Internet Explorer用户,并且现在对此感到好奇,那么可以使用这个测试平台进行测试,直到每个人都得到支持为止。

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

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!');

在旧的浏览器中使用模板语法会失败,这对于创建供公众使用的HTML很重要。使用连接是乏味且难以阅读的,特别是当您有很多或很长的表达式时,或者如果您必须使用括号来处理数字和字符串项的混合(两者都使用+运算符)。

PHP扩展带引号的字符串,其中包含变量,甚至一些表达式,使用非常紧凑的符号:$a="颜色是$color";

在JavaScript中,可以编写一个有效的函数来支持这一点:var a=S('the color is ',color);,使用可变数量的参数。虽然在本例中没有连接的优势,但当表达式变长时,语法可能会更清晰。或者可以像在PHP中那样,使用JavaScript函数使用美元符号表示表达式的开始。

另一方面,编写一个有效的变通函数来为旧浏览器提供类似模板的字符串展开并不困难。可能已经有人这么做了。

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