Setting up Method Chaining in JavaScript Classes
=====================================================
In this article, we'll explore how to set up method chaining in JavaScript classes. We'll start by looking at an example of traditional method chaining and then dive into how method chaining works when returning objects.
Traditional Method Chaining
-------------------------
When creating a function with traditional method chaining, you would typically return the object itself after each method call. This allows for a more flexible way of constructing objects.
For instance, consider this traditional method chaining:
```javascript
function createCar(color, make, model) {
var car = {};
car.color = color;
car.make = make;
car.model = model;
return car;
}
var c = createCar('pink', 'F150', 'model');
```
As you can see, the `createCar` function returns the object itself after each method call. This allows for chaining of method calls.
Method Chaining with Returning Objects
--------------------------------------
However, this approach can lead to issues when trying to chain methods on an undefined object.
```javascript
function createCar(color, make, model) {
var car = {};
car.color = color;
return car;
}
var c = createCar('pink');
c.make = 'F150';
c.model = 'model';
```
In the above example, `make` is not a valid property on an object. This is because `createCar` returns `undefined`, and you cannot call a method on `undefined`.
To fix this issue, we need to change our approach so that we are returning the object itself after each method call.
```javascript
function Car(color, make, model) {
this.color = color;
return this;
}
Car.prototype.make = function(make) {
this.make = make;
return this;
};
Car.prototype.model = function(model) {
this.model = model;
return this;
};
var c = new Car('pink', 'F150', 'model');
```
In the above code, we define a `Car` constructor that returns `this`, which allows us to chain method calls.
```javascript
var c = new Car('pink').make('F150').model();
```
As you can see, this approach is much more flexible and avoids the issue of trying to call methods on an object that has not been initialized.
Composition vs Inheritance
-------------------------
When deciding whether to use composition or inheritance in JavaScript classes, there are some key differences to consider.
Inheritance is like "is a" relationships. For example, if you have a `Human` class and a `Person` class that inherits from `Human`, then `Person` is an instance of `Human`.
Composition is more flexible than inheritance. Composition is used when you want to create an object that has a relationship with another object.
Here's an example of traditional inheritance:
```javascript
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log('The animal eats.');
};
function Human(name, age) {
this.name = name;
this.age = age;
}
Human.prototype = Object.create(Animal.prototype);
Human.prototype.constructor = Human;
Human.prototype.talk = function() {
console.log('The human talks.');
};
```
In the above example, `Human` is an instance of `Animal`, and therefore can call the `eat()` method.
However, this approach is problematic because if you add a new method to the `Animal` class, you're not sure whether it will be accessible by your `Human` class.
Composition addresses these issues:
```javascript
function Employee(name, email) {
this.name = name;
this.email = email;
}
function EmployeeDetails(ssn, salary) {
this.ssn = ssn;
this.salary = salary;
};
Employee.prototype.taxData = function() {
return new EmployeeDetails(this.ssn, this.salary);
};
```
In the above example, `Employee` has a relationship with `EmployeeDetails`, but it is not an instance of `EmployeeDetails`. Instead, `Employee` uses the `taxData()` method to create an instance of `EmployeeDetails`.
Conclusion
----------
Method chaining is a powerful tool in JavaScript classes that allows for flexible object construction. By returning objects after each method call, you can chain methods together, making your code more readable and easier to use.
In addition, composition and inheritance are different approaches to creating relationships between classes. While inheritance is useful when you want to create an "is a" relationship, composition is better suited when you want to create an object that has a relationship with another object.
By understanding these concepts and how to apply them in your code, you can write more flexible and maintainable JavaScript classes.