如何在 JavaScript 中进行字符串插值?
-
05-07-2019 - |
题
考虑这段代码:
var age = 3;
console.log("I'm " + age + " years old!");
除了字符串连接之外,还有其他方法可以将变量的值插入到字符串中吗?
解决方案
其他提示
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用户并且现在对此感到好奇,这个测试床可以用来玩,直到每个人都得到支持。
Douglas Crockford的补救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的原型,您可以随时将其调整为独立的,或将其放入其他名称空间或其他任何名称。
提醒:避免任何不允许您逃避自己的分隔符的模板系统。例如,使用此处提到的 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(" ");
尝试 sprintf 。例如:
vsprintf('The first 4 letters of the english alphabet are: %s, %s, %s and %s', ['a', 'b', 'c', 'd']);
如果您真的想使用大锤,可以使用 Prototype的模板系统破解坚果:
var template = new Template("I'm #{age} years old!");
alert(template.evaluate({age: 21}));
当我不知道如何正确地使用这种模式时,我会在很多语言中使用这种模式而只是想快速得到一个想法:
// 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'
您可以轻松地使用ES6 模板字符串
,并使用任何可用的transila像babel一样转换到ES5。
const age = 3;
console.log(`I'm ${age} years old!`);
尝试 kiwi , weight用于字符串插值的JavaScript模块。
你可以做到
Kiwi.compose("I'm % years old!", [age]);
或
Kiwi.compose("I'm %{age} years old!", {"age" : age});
这是一个需要您为对象提供值的解决方案。如果不提供对象作为参数,则默认使用全局变量。但最好坚持使用参数,它更清洁。
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>
使用 `
(重音符号也称为反引号) 而不是单引号 ('
) 或双引号 ("
) 和美元符号/括号符号 ${ variable }
例如:
console.log(
`current date: ${new Date()}`
);
阅读有关模板文字的更多信息 这里.
如果要在 console.log
输出中进行插值,则只需
console.log("Eruption 1: %s", eruption1);
^^
这里,%s
是所谓的“格式说明符”。 console.log
内置了这种插值支持。
扩展 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!');
我可以给你看一个例子:
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'));
从ES6开始,如果你想在对象键中进行字符串插值,你会得到一个 SyntaxError:expected属性名,如果你做了类似的话,得到'$ {'
:
let age = 3
let obj = { `${age}`: 3 }
您应该执行以下操作:
let obj = { [`${age}`]: 3 }
在旧版浏览器中使用模板语法失败,如果您要为公共用途创建HTML,这一点非常重要。使用连接是繁琐且难以阅读的,特别是如果您有许多或长表达式,或者您必须使用括号来处理数字和字符串项的混合(两者都使用+运算符)。
PHP使用非常紧凑的表示法扩展包含变量的引用字符串甚至一些表达式: $ a =&quot; color is $ color&quot ;;
在JavaScript中,可以编写一个有效的函数来支持这个: var a = S('color is',color);
,使用可变数量的参数。虽然在这个例子中没有优于连接的优势,但是当表达式变得更长时,这种语法可能更清楚。或者可以使用美元符号来表示使用JavaScript函数启动表达式,如在PHP中。
另一方面,编写一个有效的解决方法函数来为旧浏览器提供类似模板的字符串扩展并不难。有人可能已经做过了。
最后,我想sprintf(如在C,C ++和PHP中)可以用JavaScript编写,尽管它比其他解决方案效率低一点。
为 ES6 版@Chris Nielsen的帖子提供更多信息。
String.prototype.supplant = function (o) {
return this.replace(/\${([^\${}]*)}/g,
(a, b) => {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
string = "How now ${color} cow? {${greeting}}, ${greeting}, moo says the ${color} cow.";
string.supplant({color: "brown", greeting: "moo"});
=> "How now brown cow? {moo}, moo, moo says the brown cow."