【问题标题】:sprintf equivalent for client-side JavaScriptsprintf 等效于客户端 JavaScript
【发布时间】:2015-09-11 11:12:48
【问题描述】:

我知道console.log 至少支持来自 C 的 printf 的一些基本功能,但我很好奇有一种方法可以利用 console.log 的实现来创建类似于 @ 的东西987654326@。我知道你不能简单地使用.bind 或.apply,因为console.log 实际上并没有返回字符串,那么有没有办法解决这个问题?

如果这实际上不可能,是否还有其他一些鲜为人知的原生实现,距离在 JavaScript 中实现 sprintf 仅几行代码?

对于那些不知道sprintf 到底是什么的人,here is some documentation from tutorialspoint。我正在寻找的示例用法如下:

var string1 = sprintf("Hello, %s!", "world");
var string2 = sprintf("The answer to everything is %d.", 42);

【问题讨论】:

标签: javascript binding printf


【解决方案1】:

保持简单

var sprintf = (str, ...argv) => !argv.length ? str : 
    sprintf(str = str.replace(sprintf.token||"$", argv.shift()), ...argv);

由于 Javascript 会自动处理数据类型,因此不需要类型选项。

如果您需要填充,"15".padStart(5,"0") = ("00000"+15).slice(-5) = "00015"。

用法

var sprintf = (str, ...argv) => !argv.length ? str : 
    sprintf(str = str.replace(sprintf.token||"$", argv.shift()), ...argv);

alert(sprintf("Success after $ clicks ($ seconds).", 15, 4.569));
sprintf.token = "_";
alert(sprintf("Failure after _ clicks (_ seconds).", 5, 1.569));

sprintf.token = "%";
var a = "%<br>%<br>%";
var b = sprintf("% plus % is %", 0, 1, 0 + 1);
var c = sprintf("Hello, %!", "world");
var d = sprintf("The answer to everything is %.", 42);
document.write(sprintf(a,b,c,d));

【讨论】:

  • 我确实喜欢 $ 作为占位符的约定,特别是因为在字符串模板中键入并不是真正必需的。谢谢你这个简单的想法。
【解决方案2】:

尝试使用 eval , .replace

var sprintf = function sprintf() {
  // arguments
  var args = Array.prototype.slice.call(arguments)
    // parameters for string
  , n = args.slice(1, -1)
    // string
  , text = args[0]
    // check for `Number`
  , _res = isNaN(parseInt(args[args.length - 1])) 
             ? args[args.length - 1] 
               // alternatively, if string passed
               // as last argument to `sprintf`,
               // `eval(args[args.length - 1])`
             : Number(args[args.length - 1]) 
    // array of replacement values
  , arr = n.concat(_res)
    // `res`: `text`
  , res = text;
  // loop `arr` items
  for (var i = 0; i < arr.length; i++) {
    // replace formatted characters within `res` with `arr` at index `i`
    res = res.replace(/%d|%s/, arr[i])
  }
  // return string `res`
  return res
};

document.write(sprintf("%d plus %d is %d", 0, 1, 0 + 1) 
               + "<br>" 
               + sprintf("Hello, %s!", "world") 
               + "<br>" 
               + sprintf("The answer to everything is %d.", 42)
              );

【讨论】:

  • 看起来不错,但我不知道你为什么在里面有eval...你为什么不能再用parseInt?
  • @PatrickRoberts eval 用于评估字符串 "0+1" ;更新后的帖子将数学表达式传递为Number、+ 运算符而不是String 输入以避免使用eval。 sprintf 函数的该部分的另一个选项可能会使用 Function 。
猜你喜欢
  • 2019-11-06
  • 2020-07-18
  • 2021-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多