JavaScript equivalent to printf/String.Format

JavaScript equivalent to printf/String.Format

技术背景

在JavaScript开发中,常常需要对字符串进行格式化,将变量值插入到特定的字符串模板中,就像其他编程语言中的printfString.Format方法一样。JavaScript本身没有内置的类似方法,但有多种实现字符串格式化的方式。

实现步骤

1. ES6模板字符串

从ES6开始,可以使用模板字符串来实现字符串格式化:

1
2
3
let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!"

2. 使用第三方库

可以使用sprintf() for JavaScript库来实现类似printf的功能。

3. 自定义格式化方法

同时替换占位符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}

console.log("{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET"));
// 输出: ASP is dead, but ASP.NET is alive! ASP {2}

不修改String原型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (!String.format) {
String.format = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}

console.log(String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET'));
// 输出: ASP is dead, but ASP.NET is alive! ASP {2}

使用reduce方法

1
2
3
4
5
String.prototype.format = function() {
return [...arguments].reduce((p,c) => p.replace(/%s/,c), this);
};

console.log('Is that a %s or a %s?... No, it\'s %s!'.format('plane', 'bird', 'SOman'));

4. 数字格式化

四舍五入到指定小数位数

1
2
(12.345).toFixed(2); // 返回 "12.35"
(12.3).toFixed(2); // 返回 "12.30"

指数形式

1
(33333).toExponential(2); // "3.33e+4"

转换为其他进制

1
2
(3735928559).toString(16); // 转换为十六进制: "deadbeef"
parseInt("deadbeef", 16); // 从十六进制转换: 3735928559

核心代码

以下是一个完整的自定义格式化函数示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function sprintf() {
var args = arguments,
string = args[0],
i = 1;
return string.replace(/%((%)|s|d)/g, function (m) {
// m是匹配的格式,例如 %s, %d
var val = null;
if (m[2]) {
val = m[2];
} else {
val = args[i];
// 可以扩展格式化功能的开关语句,默认是 %s
switch (m) {
case '%d':
val = parseFloat(val);
if (isNaN(val)) {
val = 0;
}
break;
}
i++;
}
return val;
});
}

alert(sprintf('Latitude: %s, Longitude: %s, Count: %d', 41.847, -87.661, 'two'));
// 预期输出: Latitude: 41.847, Longitude: -87.661, Count: 0

最佳实践

  • ES6模板字符串:当需要简单的字符串插值时,优先使用ES6模板字符串,它语法简洁,易于理解。
  • 复杂格式化需求:如果需要实现复杂的格式化功能,如支持多种格式说明符,可以考虑使用第三方库或自定义sprintf函数。
  • 性能考虑:避免频繁修改String原型,因为这可能会影响代码的可维护性和性能。

常见问题

  • 占位符替换问题:在自定义格式化方法时,要注意同时替换占位符,避免出现替换不完整的情况。
  • 浏览器兼容性:ES6模板字符串在一些旧浏览器中可能不支持,需要进行兼容性处理。
  • 性能问题:如果在循环中频繁进行字符串格式化操作,可能会影响性能,需要考虑优化。

JavaScript equivalent to printf/String.Format
https://119291.xyz/posts/2025-05-14.javascript-equivalent-to-printf-string-format/
作者
ww
发布于
2025年5月14日
许可协议