7

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

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

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

4

3 回答 3

4

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

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

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

于 2013-04-04T18:44:52.753 回答
4
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");
于 2018-08-17T19:45:59.033 回答
-2

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

或者你可以做

var samuel = "sam";
var someNumber = 100;

var someString = samuel + " has " + someNumber + " points";
于 2013-04-04T18:48:31.890 回答