Since 2015, JavaScript has improved immensely.
It’s much more pleasant to use it now than ever.
In this article, we’ll look at new OOP features in JavaScript.
Symbol.toPrimitive Method
The Symbol.toPrimitive
lets an object customize how it’s converted to a pritmive value.
Many JavaScript operators coverts operands.
For instance, the multiplication operator converts operands to numbers.
The Date
constructor converts parameters to numbers.
parseInt
also does the same conversion.
The most common kind of values is converted to boolean, number, string, or object.
Numbers and string conversions are converted by the ToPrimitive
operation.
There’re other methods used for coercion.
They include the obj.valueOf
method to convert it primitive wrapper object to a primitive value.
To convert strings, the obj.toString
method is returned if it’s primitive.
valueOf
is called as an alternative.
The default mode is to convert to a number.
Date.prototype[Symbol.toPrimitive]
deviates from the default algorithm for conversion.
It converts the Date
instance to a timestamp.
For instance, we can override the Symbol.toPrimitive
method by writing:
const obj = {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 100;
case 'string':
return 'foo';
case 'default':
return 'default';
default:
throw new Error();
}
}
};
The hint
has the string with the mode for conversion.
And we can return what we want based on that.
Symbol.toStringTag
The Symbol.toStringTag
is a string-valued property that’s used to create the default string description of an object.
It’s used internally by the Object.prototype.toString
method.
For instance, we can create our own description by writing:
class Foo {
get[Symbol.toStringTag]() {
return 'bar';
}
}
Then when we call:
console.log(Object.prototype.toString.call(new Foo()));
Then we get:
'[object bar]'
logged.
The default return values for Symbol.toStringTag
for various kinds of objects are the following:
undefined'
—Undefined'
null
—'Null'
- array —
'Array'
- string —
'String'
arguments
—'Arguments'
- something callable —
'Function'
- error object —
'Error'
- boolean object —
'Boolean'
- number object —
'Number'
- date object —
'Date'
- regular expression object —
'RegExp'
- everything else —
'Object'
Overriding the Default toString Tag
We can override the default toString
tag by overriding the Symbo.toStringTag
method with our own method.
Built-in classes also have their own string tags.
Objects like JSON
, Math
, ArrayBuffer
, DataView
, Map
, Promise
, Set
, TypedArray
, WeakMap
, WeakSet
, etc. all have their own string tags.
The Symbol.toStringTag
methods are all non-writable, non-enumerable, but it’s configurable.
Symbol.unscopables
Symbol.unscopables
lets an object hide some properties from the with
statement.
It’s only used by the Array.prototype
in the standard library.
We shouldn’t use the with
statement, so we don’t have to worry about this.
Base Classes
Class syntax is introduced with ES6 to let us create constructors easier.
For instance, we can write:
class Person {
constructor(name) {
this.name = name;
}
toString() {
return `(${this.name})`;
}
}
We can then create the object from it by writing:
const person = new Person('james');
And we can call the toString
method by writing:
person.toString()
and get 'james'
.
If we check the type of the class with typeof
:
typeof Person
We get 'function'
.
However, if we try to call it as a function, we can write:
Person()
We’ll get the error ‘TypeError: Classes can’t be function-called’.
Conclusion
We can override common well-known symbols to change the behavior of objects.
Also, we can use the class syntax to create constructors.