This has become more of a pondering about how javascript works, than an actual problem to fix. In the case of a statement like
var str = 9 + " some words here";
The resultant str var would contain the value "9 some words here". My question is what function does javascript use to automatically coerce the Number object '9' into a string to be concatenated with the String object " some words here", and is this function changeable/overrideable.
This started from me needing to output single digits with a preceding 0 on a page. This was easy enough to accomplish with a quick prototype function on the Number object
Number.prototype.SpecialFormat = function() {
if(this < 10) {
return "0" + this;
}
else {
return this.toString();
}
};
And call it with a simple (9).SpecialFormat() + " words here";
But that got me wondering if I could overwrite the toString function on a Number with a
Number.prototype.toString = function() {
if(this < 10) {
return "0" + this;
}
else {
return this;
}
};
, and just let javascripts automatic conversion handle it for me, so I could use a standard 9 + " words here";
to get the same result "09 words here". This did not just implicitly work, I had to end up adding .toString to the 9 (9).toString() + " words here"
(which upon taking a further look, would have resulted in some infinite loops).
So is there a way to override the built in functionality of a javascript native type ?
*Note: I realize this is likely a 'worst idea ever'
Does JavaScript support automatic type conversion? Yes. It's usually called type coercion, but conversion is perfectly accurate.
And still there are only three types of conversion: numeric, string and boolean. coerced to true , no matter if an object or an array is empty or not. Objects are converted to primitives via the internal [[ToPrimitive]] method, which is responsible for both numeric and string conversion.
JavaScript is a "loosely typed" language, which means that whenever an operator or statement is expecting a particular data-type, JavaScript will automatically convert the data to that type.
Type conversion is similar to type coercion because they both convert values from one data type to another with one key difference — type coercion is implicit whereas type conversion can be either implicit or explicit.
The addition operator coerces its arguments to strings in step 7:
- If Type(lprim) is String or Type(rprim) is String, then
- Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
The ToString operation has special rules for numbers, detailed under "ToString Applied to the Number Type".
It appears that the abstract operation ToString(number)
does not ever use Number.prototype.toString
. In fact, ti's the other way around: the default Number.prototype.toString
function employs the abstract numeric ToString algorithm. Thus, it's not possible to override the default behavior for the stringification of numbers during type coercion in ECMAScript 5, because there's no way to alter the language-defined ToString operation.
ToString does use the target's toString
method when coercing objects to strings, but not number primitive values.
(not strictly an answer but I need some space)
Be very careful with type coercion, especially when combining primitive types with their object counterparts because:
var n = 9;
typeof n; // "number"
n instanceof Number; // false!!
n = new Number(9);
n instanceof Number; // true, oh thank God
typeof n; // "object" what!!
Also, toString
on Number
doesn't actually work:
Number.prototype.toString = function () { return "foo" + this; };
var n = new Number(9);
"" + n; // "9", not "foo9"
A way to avoid this mess is by having:
var ns = {
number: {
specialFormat: function () /* .. */ }
}
}
ns.number.specialFormat(9); // "09"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With