如何在JavaScript中进行字符串插值操作?
字符串插值是一种常见的编程需求,它允许我们将变量的值嵌入到字符串中。在JavaScript中,没有内置的字符串插值语法,但我们可以通过一些方法来实现。这篇文章将介绍字符串插值在JavaScript中的出现原因以及解决方法。
在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; } ); }; // 使用示例: alert("I'm {age} years old!".supplant({ age: 29 })); alert("The {a} says {n}, {n}, {n}!".supplant({ a: 'cow', n: 'moo' }));
除了修改`String`原型的方法外,我们还可以将该函数适应为独立的函数,或将它放入其他命名空间中。需要注意的是,使用该方法会比简单的字符串拼接慢10倍,并且需要更多的代码和字节。
关于性能方面,一个快速的测试结果显示,使用Crockford的方法执行"The cow says moo, moo, moo!"需要7312纳秒,而使用预编译函数从传递的对象中提取变量并与模板字符串的常量部分拼接,只需要111纳秒。这是在Chrome 21上的测试结果。
除了以上的方法,我们还可以使用类似于PHP或Ruby中的语法级插值,它会在解析代码时将插值解析为普通的字符串拼接。然而,这种解决方案会涉及多次子字符串搜索。
性能差异对于绝大部分情况来说是微不足道的,除非你需要处理大量的字符串。
此外,Crockford的方法也存在一些问题。它修改了一个我们不拥有的对象,即`String`的原型。在修改不属于我们的对象时,我们应该避免直接修改其原型。
字符串插值在JavaScript中是一个常见的需求。虽然JavaScript没有内置的字符串插值语法,但我们可以使用一些方法来实现它。Crockford的`String.prototype.supplant`函数是一个简单且易于使用的方法,但也存在一些性能和修改原型的问题。对于在代码中进行插值,我们可以使用模板字符串来实现。根据具体的需求选择合适的方法来实现字符串插值是很重要的。
在ES6之后,你可以使用模板字符串进行字符串插值:
const age = 3 console.log(`I'm ${age} years old!`)
注意使用的是反引号:``
。
我想知道他们为什么选择了反引号,"${age}"难道不足以实现插值吗?
这是为了向后兼容。如果以这种方式实现,所有以这种格式打印字符串的现有代码都将失败。
我一直不喜欢反引号作为有意义的字符。但我不确定这个原因是否普遍存在,或者只适用于我的语言的键盘布局。反引号是一种特殊的字符,等待被输入直到下一个字符,需要按两次才能输入(在此时输入两个)。这是因为某些字符与它们相互作用,比如"e"。如果我尝试用它们写"ello",我得到的是èllo``。它的位置也有点令人讨厌(shift+反引号,这是另一种特殊的前瞻字符),因为它需要按住shift键才能输入,而不像'。
这是特定于你的键盘布局的问题;你描述的被称为"死键"。在挪威的键盘布局(我的出生地)中也存在这个问题,这也是我为什么在编程时切换到美国的键盘布局的原因之一。还有其他一些字符(例如[和])在美国键盘上更容易输入。
小提示:我使用的是挪威键盘,它具有你描述的功能。你可以在输入反引号后按空格键来简单地"显示"它,而无需将其放在字符上方或强制输入两个反引号。
在ECMAScript 5规范中,没有直接的方法来进行字符串插值。然而,在ECMAScript 6中,我们可以使用模板字符串(template strings)来实现字符串插值。使用方法如下:
var n = 42; `foo${n}bar`
其中`${}`内可以使用任意有效的JavaScript表达式。例如:
`foo${{name: 'Google'}.name}bar` `foo${1 + 3}bar`
另外一个重要的点是,我们不再需要担心多行字符串的问题。可以直接使用如下方式书写多行字符串:
`foo bar`
需要注意的是,以上示例中使用了io.js v2.4.0来评估模板字符串。我们也可以使用最新版本的Chrome来测试这些示例。
需要注意的是,尽管ES6规范已经完成,但并不是所有的主流浏览器都已经实现了这一功能。根据Mozilla开发者网络页面的说明,基本支持将从以下版本开始实现:Firefox 34,Chrome 41,Internet Explorer 12。如果你是Opera、Safari或者Internet Explorer的用户,现在就可以使用这个测试平台来进行测试,直到所有浏览器都支持这一功能。
如果你使用babeljs,那么你可以将模板字符串引入到你的代码中,然后在目标浏览器支持这一功能后,可以删除转译步骤。
还有一种情况,如果我们有一个包含翻译表的json文件,需要将值插入其中以供显示,是否有办法将普通字符串转为模板字符串?对于这种情况,第一种解决方案可能适用,但总体上我还是喜欢新的字符串模板语法。
作为这个问题在搜索结果中仍然是最早的一个,希望你能更新一下,以反映现在的情况。"There is no direct way to do it"可能不再适用于大多数浏览器。
对于视力不佳的观众,反引号(`)与单引号(')是不同的。如果你在使用时遇到问题,请确保使用的是反引号。反引号在键盘上位于左上角。
在Mac键盘上是左下角,也称为反引号 🙂
我觉得你是指左上角吧?
不是,我确定在Mac(英国)键盘上是左下角。这是一个链接,你可以看一下:apple.com/uk/shop/product/MLA22B/A/…。我现在意识到美国键盘上是左上角,不知道为什么英国键盘上的位置如此奇怪(因为在英国键盘上这个位置也是不常见的)。苹果真是太奇怪了。
啊,我没意识到在英国键盘上是不同的。每天都能学到新东西呢。:)