JavaScript is object based programming language where most of the work is done using functions. A function can act like a class or a function due to its prototypical nature. From the outset people felt a need for classes and used various framework which wraps class like functionality into the language. As has been a trend with all my tutorials first of all I will try to explain how to create classes with methods, properties etc. using prototype programming model and later we will jump to new way of programming classes which resembles most of the existing and old programming languages.
Let’s create a class in JavaScript with some variables like we do in other languages
<script type="text/javascript"> //A simple class with id property function myClass(id){ var id; function helloWorld(){ } } //Usage . As you can see we create object using new and pass any //required parameters into constructor var objMyClass = new myClass(1); console.log(objMyClass.id); console.log(objMyClass.helloWorld()); </script>
Output:
Undefined
Object doesn’t support property or method ‘helloWorld’
As you can see, you can declare variable and methods inside classes but they remain in private scope unless specified using this keyword. This is important stuff since the new ES6 class feature won’t let you declare variables at all
Let’s check how to create properties and add methods at runtime as well
<script type="text/javascript"> //A simple class with id property function myClass(id){ this.id =id; } //Usage. As you can see we create object using new and pass any //required parameters into constructor. For sake of demonstration we created 2 //objects var objMyClass = new myClass(1); var objMyClassAnotherObject = new myClass(2); //Another way of adding property to existing object. //Below feature is possible becasue of dynamic nature of javascript. //Will add a new property names "newProperty" to objMyClass object only //and won't effect the prototype i.e. myClass or other existing objects objMyClass.newProperty = "This is a new property"; //Will add a new property names "newMethod" to objMyClass object only //and won't effect the prototype i.e. myClass or other existing objects objMyClass.newMethod= function(){ console.log(this.newProperty) }; console.log(objMyClass.id); console.log(objMyClass.newProperty); console.log(objMyClass.newMethod()); console.log(objMyClassAnotherObject.id); //A new property named newProperty will be added to //objMyClassAnotherObject but have a default value of undefined console.log(objMyClassAnotherObject.newProperty); //Below will throw error since we have not added newMethod to this object console.log(objMyClassAnotherObject.newMethod()); </script>
Output:
1
This is a new property
This is a new property
2
Undefined
Object doesn’t support property or method ‘newMethod’
So, as you can see from above example we can add method and properties to existing objects at runtime but it has not effect on other objects or the class definition.
We can change the class definition as well by adding properties and method to class’s prototype declarations as below
<script type="text/javascript"> //A simple class with id property function myClass(id){ this.id =id; } //Usage . As you can see we create object using new and pass any //required parameters into constructor var objMyClass = new myClass(1); var objMyClassAnotherObject = new myClass(2); myClass.prototype.newProperty = "This is a new property"; myClass.prototype.newMethod= function(){ return this.newProperty; }; console.log(objMyClass.id); console.log(objMyClass.newProperty); console.log(objMyClass.newMethod()); console.log(objMyClassAnotherObject.id); console.log(objMyClassAnotherObject.newProperty); console.log(objMyClassAnotherObject.newMethod()); </script>
Output:
1
This is a new property
This is a new property
2
This is a new property
This is a new property
As you can see once the methods and properties are added to the prototype, they become available to all objects of that class.
Like we added properties, we can also remove them at run-time
<script type="text/javascript"> //A simple class with id property function myClass(id){ this.id =id; } //Usage . As you can see we create object using new and pass any required //parameters into constructor var objMyClass = new myClass(1); var objMyClassAnotherObject = new myClass(2); objMyClass.newProperty = "This is a new property"; console.log(objMyClass.id); console.log(objMyClass.newProperty); delete(objMyClass.newProperty); console.log(objMyClass.newProperty); </script>
Output:
1
This is a new property
Undefined
More points
- There is no explicit constructor definition as such. The default function declaration will decide how constructor will look like.
- You can declare variable and methods inside a class but unless used with this keyword they will not be accessible outside the class.
- We can delete properties using delete function
With good enough understanding of what you can do with old style JavaScript classes, let’s check out the new way of creating classes using ES6
You can create a class using class keyword
<script type="text/javascript"> class MyClass{ //Wrong way. can't declare variable inside a class // let id; getId(){ return this.id; } setId(value){ this.id = value; } } var objMyclass = new MyClass(); objMyclass.setId (1); console.log(objMyclass.getId()); </script>
Output:
1
How to set default values to properties?
We can set default values to properties inside constructor like below example.
<script type="text/javascript"> class MyClass{ //Wrong way. can't declare variable inside a class // let id; constructor(){ this.id =1; } getId(){ return this.id; } setId(value){ this.id = value; } } var objMyclass = new MyClass(); // objMyclass.setId (1); console.log(objMyclass.getId()); </script>
Inheritance
We can inherit one JavaScript class from other class using extends keyword. In next example, we will see and below features:
- Call base class constructor
- Creating properties using get and set keywords
<script type="text/javascript"> class Vehicle{ constructor(fuelType){ this.fuelType = fuelType; } } class Car extends Vehicle{ constructor(fuelType, modelType){ //Call base class constructor using super keyword super(fuelType); this.modelType = modelType; } //get property syntax get manufacturer(){ return this.manufacturerName; } //set property syntax set manufacturer(value){ this.manufacturerName = value; } } var car = new Car("diesel","Ford"); car.manufacturer ="something"; console.log(car.modelType); console.log(car.manufacturer); </script>
Output:
Ford
Something
Method hiding in JavaScript using classes
Method Hiding is a concept where we declare a method with same signature in child class. Let’s try to understand method hiding in JavaScript using below example.
<script type="text/javascript"> class Vehicle{ constructor(fuelType){ this.fuelType = fuelType; } run(){ console.log("Run From base"); } } class Car extends Vehicle{ constructor(fuelType, modelType){ //Call base class constructor using super keyword super(fuelType); this.modelType = modelType; } run(){ console.log("Run From Child"); } } var vehicle = new Vehicle(); vehicle.run(); var car = new Car("diesel","Ford"); car.run(); </script>
Output:
Run From base
Run From child
So, as you can see we can hide a base class method by redefining a method with same signature in child class, thus child will point to new definition though base class still has its own version of method. Sometimes we need to call a base class method even when we have hidden the base class definition in child class. This can be done using super keyword. In next sample, we will see how to call a method of base from child class in case of hiding.
<script type="text/javascript"> class Vehicle{ constructor(fuelType){ this.fuelType = fuelType; } run(){ console.log("Run From base"); } } class Car extends Vehicle{ constructor(fuelType, modelType){ //Call base class constructor using super keyword super(fuelType); this.modelType = modelType; } run(){ super.run(); console.log("Run From Child"); } } var car = new Car("diesel","Ford"); car.run(); </script>
Output:
Run From base
Run From child
We can also define inheritance relationship with existing classes using Object.Prototype
<script type="text/javascript"> let person={ getAge(){ return 50; } }; let anotherPerson={ getAge(){ return super.getAge()+7; } } Object.setPrototypeOf(anotherPerson,person); console.log(anotherPerson.getAge()); </script>
Output:
57
With ES6 we can also define static members inside a class. Static members are accessible via class names and there is one copy of data member per class, they are not tied to objects.
<script type="text/javascript"> class Person{ static getPersonId(){ return 1; } } console.log(Person.getPersonId()); </script>
Output:
1