Earlier quoted context omitted.
> With Javascript (a weakly typed language): I'm always wary of these, because you can define that as strongly typed if it's the operation which is defined to perform the conversion internally, which IIRC is how it works in javascript. For instance the first example will do the exact same thing in Java, because addition between a string and a non-string is defined as converting the non-string to a string then concate…
> which IIRC is how it works in javascript. Yes, when objects are involved it's internally translated to: ([]).toString() + 1 This can be shown by changing the default implementation: > Array.prototype.toString = function() { return 'Boo!'; } > [] + 1; "Boo!1" Changing the prototype for Number doesn't work so I assume there's something slightly different going on there.
The answer is that addition first checks if either operand has a "primitive value" which is string-typed, if so it's a string concatenation, otherwise it's a numerical addition, at which point it converts both operands to numbers and adds them.
The primitive value of a `Number` is a `number`, so changing `Number.prototype.toString` has no effect (it's not even called). However if you set `Number.prototype[Symbol.toPrimitive]` then you can influence the rest of the process. Still won't affect an addition of primitive `number` values but:
> Number.prototype[Symbol.toPrimitive] = function(hint) { return String(this.valueOf()) }
> new Number(4) + 2
4 + new Number(2)
[numeric binops]: https://262.ecma-international.org/13.0/#sec-applystringornu...[numeric conversion]: https://262.ecma-international.org/13.0/#sec-tonumeric