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

IT技术 javascript string string-interpolation
2021-01-15 00:05:53

考虑这个代码:

var age = 3;

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

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

6个回答

从 ES6 开始,您可以使用模板文字

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

PS注意反引号的使用:``.

@felix 这是一种特定于您的键盘布局的想法;您所描述的称为“死键”。它们也出现在挪威键盘布局(我来自哪里)中,这也是我为所有编程切换到美式键盘布局的部分原因。(还有许多其他字符 - 例如 [ 和 ] - 在美式键盘上也更容易。)
2021-03-16 00:05:53
我想知道为什么他们在这上面加上反引号,“${age}”不足以进行插值吗?
2021-03-23 00:05:53
@LaughingLemonade 向后兼容性。如果以这种方式实现,则所有以该格式打印字符串的现有代码都将失败。
2021-03-28 00:05:53
@Jonathan 我总是不喜欢反引号作为一个有意义的角色。但我不确定原因是普遍存在还是仅适用于我的语言键盘布局。Backtick 是一种特殊的字符,它等待写入直到下一个字符,要求它被击中两次才能写入(并且此时写入其中两个)。这是因为某些字符与它们交互,例如“e”。如果我尝试和他们一起写“ello”,我会得到 èllo``。它的位置也有点烦人(shift+forwardtick,这是另一个这样特殊的前瞻字符),因为它需要 shift 才能键入,与 '.
2021-03-29 00:05:53

tl;博士

如果适用,请使用 ECMAScript 2015 的模板字符串文字。

解释

根据 ECMAScript 5 规范,没有直接的方法可以做到这一点,但 ECMAScript 6 有模板字符串在规范的起草过程中也被称为准文字像这样使用它们:

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

您可以在 .js 文件中使用任何有效的 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 用户并且现在对此感到好奇,这个测试床可以用来玩,直到每个人都得到支持。

@Quincy Mac 键盘的左下角 - 也称为反勾号 :)
2021-03-11 00:05:53
如果您使用babeljs它是可用的,因此您可以在您的代码库中引入它,然后一旦您需要支持的浏览器实现它,就可以删除转换步骤。
2021-03-23 00:05:53
对于视力不佳的观众来说,“性格不同于”。如果您无法使用它,请确保您使用严重引用(又名倾斜引用,反引用)en.wikipedia.org/wiki/Grave_accent它在键盘的左上角 :)
2021-03-28 00:05:53
由于这仍然是 js 字符串插值的第一个搜索结果之一,如果您现在可以更新它以反映普遍可用性,那就太好了。对于大多数浏览器来说,“没有直接的方法可以做到”可能不再适用。
2021-03-31 00:05:53
有没有办法将标准字符串转换为模板字符串文字?例如,如果有一个包含转换表的 json 文件,需要将值插入其中以进行显示?我认为第一个解决方案可能适用于这种情况,但我确实喜欢新的字符串模板语法。
2021-04-06 00:05:53

Douglas Crockford 的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 的原型,您可以随时将其调整为独立的,或者将其放入其他一些命名空间,或其他任何内容。

并且需要大约三倍的击键和字节。
2021-03-11 00:05:53
@roosteronacid - 你能对这种速度下降给出一些看法吗?比如,从 0.01s 到 0.1s(重要)或从 0.000000001s 到 0.00000001s(不相关)?
2021-03-11 00:05:53
@george:在我的机器上进行的快速测试给出了 7312 ns 的“牛说哞,哞,哞!” 将 Crockford 的方法与 111 ns 用于预编译函数,该函数从传递的对象中提取变量并将它们与模板字符串的常量部分连接起来。这是 Chrome 21。
2021-03-18 00:05:53
注意:这将比仅仅连接慢十倍。
2021-03-25 00:05:53
或者像这样使用它: "The {0} says {1}, {1}, {1}!".supplant(['cow', 'moo'])
2021-04-09 00:05:53

注意事项:避免任何不允许您转义其自己的分隔符的模板系统。例如,使用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(" ");
克里斯,我不明白这是如何解决的。我可以轻松更新示例以同时使用年龄变量和 {age} 字符串。你真的想担心你可以根据模板复制文本命名你的变量吗?--此外,自从这篇文章以来,我已经成为数据绑定库的忠实粉丝。一些,比如 RactiveJS,会让你免于充满可变跨度的 DOM。与 Mustache 不同的是,它只更新页面的那部分。
2021-03-10 00:05:53
旁注:Array.join()比直接(+样式)连接,因为浏览器引擎(包括 V8,包括节点和今天几乎所有运行 JS 的东西)已经对其进行了大规模优化,并且有很大的不同支持直接连接
2021-03-23 00:05:53
supplant 方法确实允许您生成您提到的字符串:仅当数据对象包含一个被调用的成员时才会替换 {token} token- 因此,如果您不提供具有age成员的数据对象,那就没问题了
2021-03-28 00:05:53
您关于“警告”的说法supplant是没有根据的:"I am 3 years old thanks to my {age} variable.".supplant({}));准确返回给定的字符串。如果age给出,仍然可以打印{}使用{{age}}
2021-04-06 00:05:53
您的主要答案似乎假设此 javascript 正在浏览器环境中运行,即使该问题没有用 HTML 标记。
2021-04-07 00:05:53

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

// JavaScript
let 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'
它也适用于一组键/值对和一个循环
2021-03-20 00:05:53
IE 不支持模板文字,因此当您不想需要单独的包(例如 sprintf)时,这是一个不错的解决方案。比连接字符串更干净,尤其是在处理具有动态属性和内容的 html 标签时。
2021-04-09 00:05:53