【问题标题】:Native Javascript printf-like function本机 Javascript 类 printf 函数
【发布时间】:2013-04-04 18:40:08
【问题描述】:

Chrome 和 Firefox 等浏览器提供 console API,可以发送格式化的日志消息,如下所示:

>>> console.log("%s has %d points", "Sam", "100");
Sam has 100 points

现在,假设我想生成一个格式化的字符串,但不一定要将它记录到控制台中。浏览器是否公开了生成日志字符串的本机函数?它是 ECMA 标准吗?还是我们现在应该满足于第三方库,例如JavaScript sprintf

【问题讨论】:

  • 还没有原生,但这里有一个库 - diveintojavascript.com/projects/javascript-sprintf
  • @Ian 是的!问题中提到了。这个库令人印象深刻。
  • 天哪,我是个白痴。哈哈,我什至没有在问题中注意到它,对此感到抱歉。链接的文字很枯燥,因为我以前访问过它,所以它与其他文字混合在一起(我显然没有完全阅读你的问题):(

标签: javascript console string-formatting


【解决方案1】:

ES6 会以如下形式引入一些基本的字符串格式化:

`${name} has ${val} points`;

但目前 ES5 中没有原生字符串格式。

【讨论】:

  • 这和printf不太相似,这里应该定义name和val
【解决方案2】:
Object.defineProperty(String.prototype, "printf",
        {
            value: function()
                {
                    var args = Array.from(arguments), i = 0;
                    function defaultNumber(iValue)
                    {
                        return ((iValue != undefined) && !isNaN(iValue) ? iValue: "0");
                    }
                    function defaultString(iValue)
                    {
                        return (iValue == undefined? "": "" + iValue);
                    }
                    return this.replace(/%%|%([+\-])?([^1-9])?(\d+)?(\.\d+)?([deEfhHioQqs])/g,
                        function (match, sign, filler, scale, precision, type)
                            {
                                var strOut, space, value;
                                var asNumber = false;
                                if (match == "%%")
                                    return "%";
                                if (i >= args.length)
                                    return match;
                                value = args[i];
                                while (Array.isArray(value))
                                {
                                    args.splice(i, 1);
                                    for (var j = i; value.length > 0; j++)
                                        args.splice(j, 0, value.shift());
                                    value = args[i];
                                }
                                i++;
                                if (filler == undefined)
                                    filler = " "; // default
                                if ((scale == undefined) && !isNaN(filler))
                                {
                                    scale = filler;
                                    filler = " ";
                                }
                                if (sign == undefined) sign = ("sqQ".indexOf(type) >= 0? "+": "-"); // default
                                if (scale == undefined) scale = 0; // default
                                if (precision == undefined) precision = ".0"; // default
                                scale = parseInt(scale);
                                precision = parseInt(precision.substr(1));
                                switch (type)
                                {
                                    case 'd':
                                    case 'i':
                                        // decimal integer
                                        asNumber = true;
                                        strOut = parseInt(defaultNumber(value));
                                        if (precision > 0)
                                            strOut += "." + "0".repeat(precision);
                                        break;
                                    case 'e':
                                    case 'E':
                                        // float in exponential notation
                                        asNumber = true;
                                        strOut = parseFloat(defaultNumber(value));
                                        if (precision == 0)
                                            strOut = strOut.toExponential();
                                        else
                                            strOut = strOut.toExponential(precision);
                                        if (type == 'E')
                                            strOut = strOut.replace('e', 'E');
                                        break;
                                    case 'f':
                                        // decimal float
                                        asNumber = true;
                                        strOut = parseFloat(defaultNumber(value));
                                        if (precision != 0)
                                            strOut = strOut.toFixed(precision);
                                        break;
                                    case 'o':
                                    case 'h':
                                    case 'H':
                                        // Octal or Hexagesimal integer notation
                                        strOut = '\\' + (type == 'o'? '0': type) +
                                            parseInt(defaultNumber(value)).toString((type == 'o'? 8: 16));
                                        break;
                                    case'q':
                                        // single quoted string
                                        strOut = "'" + defaultString(value) + "'";
                                        break;
                                    case'Q':
                                        // double quoted string
                                        strOut = '"' + defaultString(value) + '"';
                                        break;
                                    default:
                                        // string
                                        strOut = defaultString(value);
                                        break;
                                }
                                if (typeof strOut != "string")
                                    strOut = ("" + strOut);
                                if ((space = strOut.length) < scale)
                                {
                                    if (asNumber)
                                    {
                                        if (sign == "-")
                                        {
                                            if (strOut.indexOf('-') < 0)
                                                strOut = filler.repeat(scale - space) + strOut;
                                            else
                                                strOut = '-' + filler.repeat(scale - space) + strOut.replace("-","");
                                        }
                                        else
                                        {
                                            if (strOut.indexOf('-') < 0)
                                                strOut = '+' + filler.repeat(scale - space - 1) + strOut;
                                            else
                                                strOut = '-' + filler.repeat(scale - space) + strOut.replace("-","");
                                        }
                                    }
                                    else
                                    {
                                        if (sign == "-")
                                            strOut = filler.repeat(scale - space) + strOut;
                                        else
                                            strOut = strOut + filler.repeat(scale - space);
                                    }
                                }
                                else if (asNumber && (sign == '+') && (strOut.indexOf('-') < 0))
                                    strOut = '+' + strOut;
                                return strOut;
                            });
                }
        });

    Object.defineProperty(window, "printf",
        {
            value: function(str, ...rest)
            {
                if (typeof str == "string")
                    return String.prototype.printf.apply(str,rest);
                return "";
            }
        });
printf("Your Name is:%_30s your age is: %o\nyour wish is: %20q;", "Tom Johnson",48,"Lotto Numbers");

产量:

"Your Name is:Tom Johnson___________________ your age is: \\060
your wish is: 'Lotto Numbers'     ;"

你也可以这样调用它:

"Your Name is:%_30s your age is: %o\nyour wish is: %20q;".printf("Tom Johnson",48,"Lotto Numbers");

【讨论】:

    【解决方案3】:

    我不认为你可以在本地做到这一点。您可以编写自己的 javascript toString 函数来处理不同的选项。

    你也可以这样做

    var samuel = "sam";
    var someNumber = 100;
    
    var someString = samuel + " has " + someNumber + " points";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      • 2012-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多