The solution varies based on whether you are utilizing ES5 or earlier versions, as opposed to ES2015 and later.
For ES2015 and beyond
Yes, it is possible to apply the Symbol.toPrimitive
method on your prototype and determine the hint it receives as the first argument:
// (A more comprehensive ES2015+ version can be seen below,
// this example remains relatively ES5-like for comparison with the ES5 version)
function MyObject(num, name) {
this.num = num;
this.name = name;
}
MyObject.prototype[Symbol.toPrimitive] = function(hint) {
return hint === "number" ? this.num : this.name;
};
var a = new MyObject(21, "half the answer");
console.log(a * 2); // 42
console.log("It says it's " + a); // It says it's half the answer
It is highly unlikely that this will function properly on a purely ES5 JavaScript engine even with transpilation...
Note that the code above has been kept fairly ES5-like for easy comparison with the ES5 version provided earlier. However, in ES2015 and beyond, we would likely write it as follows:
class MyObject {
constructor(num, name) {
this.num = num;
this.name = name;
}
[Symbol.toPrimitive](hint) {
return hint === "number" ? this.num : this.name;
}
}
let a = new MyObject(21, "half the answer");
console.log(a * 2); // 42
console.log("It says it's " + a); // It says it's half the answer
For ES5 and prior versions
You do not have as much control as JavaScript itself does, where it utilizes the "hint" on the abstract ToPrimitive
operation to select valueOf
or toString
in a special manner for Date
.
However, you can come close by implementing valueOf
and toString
. When your object is coerced into a number, valueOf
will be utilized. When coerced into a string, toString
will be employed.
Yet, it should be noted that +
will use
valueOf</code even if the other operand is a string:</p>
<p>Example:</p>
<p><div>
<div>
<pre class="lang-js"><code>function MyObject(num, name) {
this.num = num;
this.name = name;
}
MyObject.prototype.valueOf = function() {
return this.num;
};
MyObject.prototype.toString = function() {
return this.name;
};
var a = new MyObject(21, "half the answer");
console.log(a * 2); // 42
console.log("It says it's " + a); // It says it's 21
console.log("It says it's " + String(a)); // It says it's half the answer