Best of Modern JavaScript — Symbols and Base Classes

John Au-Yeung - Jul 30 '20 - - Dev Community

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.

The post Best of Modern JavaScript — Symbols and Base Classes appeared first on The Web Dev.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .