After completing this lesson, you will be able to:
After completing this lesson, you will be able to:
Identify the main concepts of object-oriented programming (OOP)
Introduction to Object-Oriented Programming (OOP)
OOPs Concepts
JavaScript is an object-oriented programming language, but it uses a different model than most other object-oriented languages, such as Java or C#. JavaScript uses prototypes instead of classes for inheritance, which is a form of object-oriented inheritance that relies on shared objects.
Here are the main concepts of object-oriented programming in JavaScript:
Objects: In JavaScript, an object is a standalone entity, with properties and type. It can be seen as a container that holds related data and methods used to manipulate that data. You can create an object using the object literal syntax or the new keyword.
Properties: A JavaScript object has properties associated with it. A property of an object can be explained as a variable that is attached to the object.
Methods: Methods are functions that are associated with an object. They define the behaviors or functionalities that an object can perform.
Prototype Inheritance: In JavaScript, each object has a prototype object, which acts as a template object from which it inherits methods and properties. An object’s prototype object may also have a prototype object, from which it inherits methods and properties, and so on. This is often referred to as a prototype chain.
Constructors: In JavaScript, the constructor method is a special method for creating and initializing an object. A constructor can use the this keyword to reference the object that will be created and initialized.
thisKeyword: In JavaScript, this is a special keyword that is used in methods to refer to the object on which a method is called. It's a reference to the object the method was called upon.
Encapsulation: This is the practice of keeping fields within a JavaScript object private, so they can only be accessed and modified through methods of their containing object. This is usually done by defining them as local variables within the object constructor.
Polymorphism: While JavaScript doesn't support polymorphism in the traditional sense due to lack of type-checking, it can achieve a similar outcome because it's dynamically typed. This means you can overwrite or change methods and properties in a way that's more flexible than in statically typed languages.
Note
Note that with the introduction of ES6 (ECMAScript 2015), JavaScript introduced a class syntax that allows developers to write classes that work much like they do in other object-oriented languages. However, it's important to understand that under the hood, this is just syntactic sugar, and JavaScript still uses prototypes for inheritance.
Object Prototypes
Introduction
In JavaScript, almost everything is an object, and every object has a special internal property called [[Prototype]]. This property is a link to another object, the object's prototype. When trying to access a property that does not exist in an object, JavaScript will look for that property in the object's prototype. This is known as prototype chaining.
Prototype Chaining
Prototype chaining allows objects to "inherit" properties from their prototype objects. Here's an example.
Code snippet
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal // sets rabbit's prototype to be the animal object
};
console.log(rabbit.eats); // true
In this example, rabbit doesn't have the eats property itself. However, when we call rabbit.eats, JavaScript checks the rabbit object, doesn't find the eats property, then moves up to the rabbit's prototype (which is animal) and finds the eats property there.
Constructor Function and prototype Property
JavaScript provides constructor functions for creating new objects. The prototype property in JavaScript is a pre-existing property on constructor functions that gives us a place to add methods and properties that are shared across all instances of a constructor function.
Here, sayFullName is a method on the Person.prototype that all instances of Person can access.
Prototypes are Shared Among All Instances
When a method is added to the prototype, that method is shared among all instances. This is efficient because it saves memory. The method isn't duplicated for each instance. Instead, each instance references the method located on the prototype.
Prototype Chain and Inheritance
One powerful feature of prototypes in JavaScript is the ability to simulate inheritance, which is a key aspect of OOP.
Code snippet
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(this.name + ' eats.');
}
function Rabbit(name) {
this.name = name;
}
Rabbit.prototype = Object.create(Animal.prototype); // Rabbit now inherits from Animal
Rabbit.prototype.jump = function() {
console.log(this.name + ' jumps.');
}
let rabbit = new Rabbit('Bunny');
rabbit.eat(); // "Bunny eats."
rabbit.jump(); // "Bunny jumps."
Here, Rabbit inherits from Animal by setting Rabbit.prototype to Object.create(Animal.prototype). As a result, a Rabbit instance can access methods defined in Animal.prototype.
Conclusion
Understanding prototypes in JavaScript is crucial because it is a fundamental part of the language. It allows for efficient memory usage through shared methods, and it enables inheritance, a key aspect of OOP.
Class
Introduction
In JavaScript, classes are a way to create objects with specific properties and methods. They are essentially syntactic sugar over JavaScript's existing prototype-based inheritance. The class syntax doesn't introduce a new object-oriented inheritance model to JavaScript, but provides a much simpler and cleaner way to create objects and deal with inheritance.
Defining and Instantiating Classes
To define a class, you use the class keyword followed by the name of the class.
The constructor method is a special method for creating and initializing objects created with a class. It runs automatically when a new object is created.
To create a new instance of a class, you use the new keyword.
Refer to the following code snippet.
Code snippet
let rectangle = new Rectangle(10, 5);
console.log(rectangle.height); // 10
console.log(rectangle.width); // 5
In this example, Rectangle is a subclass of Shape. The super keyword is used to call the constructor of the parent class.
Conclusion
Classes in JavaScript provide a simpler and more intuitive way to deal with objects and inheritance. They allow for a cleaner and more readable syntax for generating object instances and handling prototype-based inheritance. Understanding classes and how they work is fundamental to mastering JavaScript.