Class Basic Syntax

Class Basic Syntax

Class Basic Syntax


Frequently it is necessary to create many objects of the same kind. As it was already noted in chapter Constructor, operator “new”, you can do it with the help of the new function.

In modern JavaScript, there exists a more advanced “class” construct, introducing new features that are useful for object-oriented programming.

The “class” Syntax

The syntax is as follows:

class MyClass {
  // class methods
  constructor() { ...
  }
  method1() { ...
  }
  method2() { ...
  }
  method3() { ...
    }
    ...
}

Then it would be best if you used new MyClass() for creating a new object including all the listed methods.

The constructor() method is automatically invoked by new. Hence, the object can be initialized there.

For instance:

class Site {

  constructor(siteName) {

    this.siteName = siteName;

  }

  welcome() {

    console.log(this.siteName);

  }

}

// Usage:

let site = new Site("Web");

site.welcome();

At the time a new Site("W3Docs") is called, a new object is generated. Besides, the constructor runs with a particular argument assigning this.siteName to it.

Then you can call object methods. For example, site.welcome().

It is essential to know that you should not put a comma between class methods. It results in a syntax error.

Describing a Class

For a better understanding of many complex aspects, it’s necessary to learn what a class is.

So, a JavaScript class is a kind of function.

For instance:

class Site {

  constructor(siteName) {

    this.siteName = siteName;

  }

  welcome() {

    console.log(this.siteName);

  }

}

// proof: Site is a function

console.log(typeof Site); // function

The class Site {...} construct operates as follows:

  • It generates a function, known as Site, which becomes the result of the class declaration. The function code is derived from the constructor method.
  • It stocks class methods (welcome, in Site.prototype).

Following the creation of the new Site object, it is taken from the prototype. It means that the object has access to class methods.

The class Site declaration is illustrated in the picture below:

The code looks like this:

class Site {

  constructor(siteName) {

    this.siteName = siteName;

  }

  welcome() {

    console.log(this.siteName);

  }

}

// class is a function

console.log(typeof Site); // function

// ...or, more precisely, the constructor method

console.log(Site === Site.prototype.constructor); // true

// The methods are in Site.prototype, e.g:

console.log(Site.prototype.welcome); // cosnole.log(this.siteName);

// there are exactly two methods in the prototype

console.log(Object.getOwnPropertyNames(Site.prototype)); // constructor, welcome

More Than a “syntactic sugar”

Often the class is compared to “syntactic sugar” (a syntax that is aimed at making things easy-readable not introducing anything new) as it is possible to declare the same without using the class keyword.

Take a look at this example:

// rewriting class Site in pure functions

// 1. Create constructor function

function Site(siteName) {

  this.siteName = siteName;

}

// any function prototype has constructor property by default,

// so we don't need to create it

// 2. Add the method to prototype

Site.prototype.welcome = function () {

  console.log(this.siteName);

};

// Usage:

let site = new Site("Web");

site.welcome();

But there exist notable differences:

  1. First of all, a function that class creates is stamped by a unique internal property, such as [[FunctionKind]]:"classConstructor".

    In contrast with a regular function, a class constructor should be called with new:

class Site {
  constructor() {}
}
console.log(typeof Site); // function
Site(); // Error: Class constructor Site cannot be invoked without 'new'
  1. The class methods are considered non-enumerable. The definition of the class sets enumerable flag to false overall methods in the "prototype".

    Note that in case you for..in over an object, commonly you don’t want the class methods.

  2. The use strict is always used by the classes. So, the code inside the class construct is by default in strict mode.

Class Expression

Classes are like functions: they can be defined inside another expression, assigned, passed around, returned, and more.

is a class expression example:

let Site = class {
  welcome() {
    console.log("Web");
  }
};

The class expression can have a name. But its name is visible only inside the class.

For instance:

// "Named Class Expression"

// that's similar to Named Function Expression, but no such term in the spec

let Site = class MyClass {

  welcome() {

    console.log(MyClass); // MyClass name is visible only inside the class

  }

};

new Site().welcome(); // works, shows MyClass definition

console.log(MyClass); // error, MyClass name isn't visible outside of the class

You even have the option of making “on-demand” classes, as follows:

function createClass(message) {

  // declare a class and return it

  return class {

    welcome() {

      console.log(message);

    };

  };

}

// Create a new class

let Site = createClass("Welcome to Web");

new Site().welcome(); // Welcome to Web

Shorthands

Like literal objects, classes can include shorthands, such as getter/setters, computer properties, and more.

In this example, the getter/setter is used:

class Site {

  constructor(siteName) {

    // invokes the setter

    this.siteName = siteName;

  }

  get siteName() {

    return this._siteName;

  }

  set siteName(value) {

    if (value.length < 3) {

      console.log("Site name is too short.");

      return;

    }

    this._siteName = value;

  }

}

let site = new Site("Web");

console.log(site.siteName); // Web

site = new Site(""); // Site name is too short.

The class declaration generates getters and setters inside Site.prototype, as follows:

Object.defineProperties(Site.prototype, {
  siteName: {
    get() {
      return this._siteName
    },
    set(siteName) {
      // ...
    }
  }
});

Another example includes computed property name in brackets [...]:

class Site {

  ['say' + 'Welcome']() {

    console.log("Welcome to Web");

  }

}

new Site().sayWelcome();

Class Properties

Let’s try to add a property to the example above:

class Site {

  siteName = "Web";

  welcome() {

    console.log(`Welcome to ${this.siteName}!`);

  }

}

new Site().welcome();

console.log(Site.prototype.welcome); // placed in Site.prototype

console.log(Site.prototype.siteName); // undefined, not placed in Site.prototype

The name of the property is not placed into Site.prototype. It is generated by new before running the constructor. It’s a property of the object.

Reactions

Post a Comment

0 Comments

close