Symbols Are Your Friend Series
- Part I: A Gentle Introduction
- Part II: Symbol.for() & Symbol.keyFor()
- Part III: Symbol.iterator
- Part IV: Symbol.search, Symbol.split, & Symbol.species
I know. You haven't gotten your fill of symbols yet. Rest assured, there's more! This week, we'll take a look at the following symbol static properties:
Symbol.toPrimitive
Symbol.toStringTag
Symbol.unscopables
Symbol.toPrimitive
This symbol defines the method to convert an object to a primitive.
Default behavior:
const arr = [1, 2, 3];
`${arr}`; // "1,2,3"
Symbol.toPrimitive
utilization:
const arr = [1, 2, 3];
arr[Symbol.toPrimitive] = function(type) {
const doubled = arr.map(item => {
return item * 2;
});
return `doubled: ${doubled}`;
};
`${arr}`; // "doubled: 2,4,6"
Symbol.toStringTag
This symbol defines the behavior of an object when it is converted into its default string description. Essentially it lets you modify the value of Object
in "[object Object]"
when Object.prototype.toString()
is used:
Default behavior:
const shows = {
cartoon: 'DuckTales',
sitcom: 'Seinfeld',
crime: 'NCIS'
};
Object.prototype.toString(shows); // "[object Object]"
Symbol.toStringTag
utilization:
Note that Symbol.toStringTag
is a string valued property (and not a method).
const shows = {
cartoon: 'DuckTales',
sitcom: 'Seinfeld',
crime: 'NCIS'
};
shows[Symbol.toStringTag] = 'Shows';
shows.toString(); // "[object Shows]"
One thing that's odd about this symbol is that it does not seem to work with anything other than objects:
const arr = [1, 2, 3];
arr[Symbol.toStringTag] = 'Numbers';
Object.prototype.toString(arr); "[object Object]"
const str = 'My string';
str[Symbol.toStringTag] = 'Custom String';
Object.prototype.toString(str); "[object Object]"
If anyone knows why, please comment!
Symbol.unscopables
This symbol is so incredibly useless but it at least introduced the with
statement to me which I had never see before. Essentially, Symbol.unscopables
modifies the behavior of with
. So what exactly does that do?
with
allows you to create a scope to a statement. The syntax is as follows:
with (expression)
statement
Here's an example:
with ({ first: 'Charles', last: 'Bronson' }) {
console.log(`Hi ${first} ${last}!`);
// Logs "Hi Charles Bronson!
}
So yeah, that's all it does. Also note that with
is deprecated as it has browser compatibility issues.
So all Symbol.unscopables
allows you to do is define what properties of an object are excluded from a with
environment binding:
const actor = {
first: 'Charles',
last: 'Bronson'
};
actor[Symbol.unscopables] = {
last: true
};
with (actor) {
console.log(first); // Logs "Charles"
console.log(last); // Logs ReferenceError
}
More symbols in the next article! π
Check out more #JSBits at my blog, jsbits-yo.com. Or follow me on Twitter.
Top comments (1)
Nice article !
Symbols are really a cool feature, although I guess they're not that much used since basically using
Symbol.toPrimitive
andSymbol.toStringTag
is globally the same as usingvalueOf()
andtoString()
(although like you said there's a few differences).More features is always a plus, since it allows you to bend the languages to your will rather than the contrary.
That's why I'm kind of sad that
with
was trashed out. I understand why some people didn't like it, but a shame it didn't stick around. Would have been quite cool to usewith (this)
in ES classes to mimic other languages like C++ or Java wherethis
is implicit inside a class.