Last active
October 20, 2020 09:37
-
-
Save dtipson/7debac370d2aded7fd1055d0e252a946 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var object = { | |
value:5, | |
increment(){ return ++this.value; } | |
}; | |
/* | |
But of course, even though that value is central to what the object is, | |
it's not really a _primitive_ value in the sense that we can directly coerce it into a number or string: | |
*/ | |
Number(object); //-> NaN | |
`${object}`; //-> [object Object] | |
//but now we define some custom behavior for coercion on complex objects. Let's look at this object I've already created | |
//->object2 | |
//Like the first object, it's a real object with both a value key and an increment key that defines a method on it | |
//Object.keys(object2);//-> ["value", "increment"] | |
//JSON.stringify(object2);//"{"value":5}" | |
//But now when we coerce it to a primitive value... | |
//Number(object2); //-> 5 | |
//`${object2}`; //-> "5" | |
//Here's what's actually going on under the hood: | |
var object2 = { | |
value:5, | |
increment(){ return ++this.value; }, | |
[Symbol.toPrimitive](hint){ | |
if (hint === "number") { | |
return this.value; | |
} | |
if (hint === "string") { | |
return String(this.value); | |
} | |
return true; | |
} | |
}; | |
/* | |
So, defining Symbol.toPrimitive allows you to alter what happens when a complex value is coerced into a string or a number. | |
You can do the same thing for arrays. Here I have an array of prices, and I can make it such that coercing it into a string | |
or a number will automatically sum its contents and return them instead of doing something weird: | |
*/ | |
var cartPrices = [10,20,30]; | |
var sum = Symbol('sum'); | |
var summable = { | |
[sum]: function(){ return this.reduce((acc,item)=>acc+item,0); }, | |
[Symbol.toPrimitive]: function(hint){ | |
if(hint==="number"){ | |
return this[sum](); | |
} | |
if(hint==="string"){ | |
return String(this[sum]()); | |
} | |
return true; | |
} | |
}; | |
//extending cartPrices with new behavior | |
Object.assign(cartPrices, summable);//-> [10, 20, 30] | |
console.log( | |
"total: $"+String(cartPrices), //-> "total: $60" | |
`total: $${cartPrices}`, //-> "total: $60" | |
Number(cartPrices) //-> 60 | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment