Getting started with JavaScript classes.

This post familiarizes you with JavaScript classes: how to define a class, constructor, initialize the instance and define methods.

1. Definition

The special keyword class defines a class in JavaScript:

class User {
  //Body of the class
}

The code above defines a class User.

The class becomes useful when you create an instance of the class. An instance is an object containing data and behavior described by the class.

Initialiazation: Constructor()

Constructor(param1, param2, ...) is a special method in the body of a class that initializes the instance. That’s the place where you set the initial values for the fields, or do any kind of object setup.

The new operator is used to create new instances based on a constructor function.

Inside the constructor this value equals to the newly created instance.

const myUser = new User();

//new User() creates an instance of the User class.

In the following example the constructor sets the initial value of the field name:

class User {
  constructor(name) {
    this.name = name;
  }
}

User’s constructor has one parameter name, which is used to set the initial value of the field this.name.

class User {
  constructor(name) {
    this.name = name;
  }
}

const user = new User('Jon Snow');

The expression this.name = name creates an instance field name and assigns to it an initial value.

Later you can access name field using a property accessor:

const user = new User('Jon Snow');
user.name; // => 'Jon Snow'

Methods

JavaScript methods are actions that can be performed on objects. A JavaScript method is a property containing a function definition.

Methods are also functionds

For example, let’s define a method getName() that returns the name in the User class:

 class User {
    constructor(name) {
    this.name = name;
  }

  getName() {
    return this.name;
  }
}

const user = new User('Jon Snow');
user.getName(); // => 'Jon Snow'

getName() { ... } is a method inside the User class. user.getName() is a method invocation: it executes the method and returns the computed value if any.

Private Fields

Another aspect of the Class Fields proposal are “private fields”.

Sometimes when you’re building a class, you want to have private values that aren’t exposed to the outside world.

There are two main parts of this x:

  1. Defining private fields
  2. Referencing private fields

Defining Private Fields

Defining private fields is mostly the same as defining public fields:

The syntax (currently) looks like this:

To make fields private, just give them a name starting with #.

class Foo {
  publicFieldName = 1;
  #privateFieldName = 2;
}

In order to access a private field, you need to have defined it. So in case you don't want to instantiate a value when defining the property, you can do so:

class Foo {
  #privateFieldName;
}

Referencing private fields

Referencing private fields works similar to accessing any other property, only it has a special syntax.

class Foo {
  publicFieldName = 1;
  #privateFieldName = 2;
  add() {
    return this.publicFieldName + this.#privateFieldName;
  }
}

There's also a shorthand version of this.#:

which is the same as:

method(){
  this.#privateFieldName;
}

So why the hashtag? Why don't declarations use the private keyword?

A lot of people are wondering "why not follow conventions from many other languages and use a private keyword"?

Here's an example of that syntax:

class Foo {
  private value;

  equals(foo) {
    return this.value === foo.value;
  }
}

The private keyword is used in a lot of different languages to declare private fields. Let's look at the syntax of language like that:

class EnterpriseFoo {
  public bar;
  private baz;
  method() {
    this.bar;
    this.baz;
  }
}

In these languages, public and private fields are accessed the same way. So it makes sense that they get defined this way.

We need to use this.#field instead of this.field.

JavaScript Accessors (Getters and Setters)

In Javascript, getters and setters are used for defining Object Accessors(Computed Properties). Accessor uses a function to get or set the value of an Object.

Accessors are useful when some operations are needed to be performed automatically before setting or retrieving an object’s value, like reformating strings, accessing private properties, triggering events, etc.

get - to define a getter method to get the property value.

set - to define a setter method to set the property value.

You can create getters and setters in three different ways:

JavaScript Getter

The easiest way to get the properties of an object is by defining a getter using the default method syntax for each of the properties.

To keep it simple, let’s consider a common scenario, where we wanted to get a user’s full name from the below object.

let user = {
  firstName: 'Metro',
  lastName: 'Boomin',
}

We can achieve this by concatenating the firstName and lastName properties of the user object.

let fullName = `${user.firstName} ${user.lastName}`;
console.log(fullName);
// 'Metro Boomin'

The above code works fine, but there is a better way to achieve the same. Let’s look at the example below:

let user = {
  firstName: 'Metro',
  lastName: 'Boomin',
  get fullName () {
 return `${user.firstName} ${user.lastName}`;
  }
}

We defined a getter named fullName in the above object to return the complete name of the user. Now full name can be accessed like any other properties of the object.

console.log(user.fullName)
// 'Metro Boomin'

So, in the above example, we achieved our requirement of concatenating two properties of an object before retrieving the required value i.e. fullName.

JavaScript Setter

The setter is used to do some required operations before setting the value of an object.

For example, you have an input field for the user’s name. But, the object in which the value needs to be stored is having firstName and lastName.

let user = {
  firstName: 'Metro',
  lastName: 'Boomin'
}

To achieve this, we will use setter.

let user = {
  firstName: 'Metro',
  lastName: 'Boomin',
  set fullName (name) {
    let [fName, lName] = name.split(' ');
    this.firstName= fName; 
    this.lastName = lName;
  }
};

Now to set the value of firstName and lastName, we can simply assign fullName like an object property and our setter function will handle the rest.

user.fullName = 'Peter Parker'

console.log(user.firstName);
//Peter
console.log(user.lastName);
//Parker

Static Methods

Unlike instance methods, static methods aren't tied to an instance of a class. They can be called even without an instance ever being created. Because of this, they're defined in a separate scope than instance methods.

Statics are on the class itself (the constructor function) while instance members are defined in the prototype. Because of this, you can have static methods with the same name as instance methods without them clashing. You just have to make sure you're referencing them from the correct object, the constructor (static members) or the instance (instance members).

Syntax

To declare a static method, simply prefix a method declaration with the word static inside the class declaration.

class Foo(){
   static methodName(){
      console.log("bar")
   }
}

Since these methods operate on the class instead of instances of the class, they are called on the class. There are two ways to call static methods:

Foo.methodName() 
// calling it explicitly on the Class name
// this would give you the actual static value. 

this.constructor.methodName() 
// calling it on the constructor property of the class
// this might change since it refers to the class of the current instance, where the static property could be overridden

Note that for static methods, this keyword references the class. You can call a static method from another static method within the same class using this.

Hope this was useful! Let me know in the comments.

No Comments Yet