Chrome 和 Firefox 等浏览器提供了一个console
API,可以发送格式化的日志消息,如下所示:
>>> console.log("%s has %d points", "Sam", "100");
Sam has 100 points
现在,假设我想生成一个格式化的字符串,但不一定要将它记录到控制台中。浏览器是否公开了生成日志字符串的本机函数?它是 ECMA 标准吗?还是我们现在应该满足于第三方库,例如JavaScript sprintf?
Chrome 和 Firefox 等浏览器提供了一个console
API,可以发送格式化的日志消息,如下所示:
>>> console.log("%s has %d points", "Sam", "100");
Sam has 100 points
现在,假设我想生成一个格式化的字符串,但不一定要将它记录到控制台中。浏览器是否公开了生成日志字符串的本机函数?它是 ECMA 标准吗?还是我们现在应该满足于第三方库,例如JavaScript sprintf?
ES6 会以如下形式引入一些基本的字符串格式化:
`${name} has ${val} points`;
但目前 ES5 中没有原生字符串格式。
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");
我不认为你可以在本地做到这一点。您可以编写自己的 javascript toString 函数来处理不同的选项。
或者你可以做
var samuel = "sam";
var someNumber = 100;
var someString = samuel + " has " + someNumber + " points";