A class is like a blueprint
, a description of objects to be created. Classes inherit from classes and create subclass relationships
.
Instantiation happens via new
operator. The class
keyword in Javascript is just a function
Class Foo{}
typeof Foo // 'function'
Classical inheritance in Javascript uses prototype chain to wire the child's Constructor.prototype
to the parent's Constructor.prototype
and usually the super()
constructor is called. This creates a tight coupling.
A prototype is a working instance. Objects can inherit directly from other objects. Instances may be composed from many source objects.
This creates a flat [[Prototype]]
delegation hierarchy. Objects are instantiated via factory functions, object literals or Object.create
.
Javascript has three kinds of prototypal inheritance
- Concatenative Inheritance - Object.assign
- Prototype delegation - Object.create
- Functional Inheritance - In JS any function can create object. Its called a factory function.
class Person {
constructor({ firstName = 'Hello', lastName = 'World' } = {}) {
Object.assign(this, {
firstName,
lastName
});
}
}
class Facebook extends Person {
constructor(options = {}) {
super(options);
this.facebookId = options.facebookId || undefined;
}
}
class LoggedIn extends Facebook {
constructor(options = {}) {
super(options);
this.isLoggedIn = options.isLoggedIn || undefined;
}
}
export { Person, Facebook, LoggedIn };
/**
* TEST
*/
describe('Class Inheritance', () => {
it('should inherit from Person and FacebookProfile', () => {
const user = new Facebook();
const actual = Object.keys(user);
const expected = ['facebookId', 'firstName', 'lastName'];
expect(actual.sort()).toEqual(expected);
});
it('should should inherit props from Person, Facebook and LoggedIn', () => {
const user = new LoggedIn();
const actual = Object.keys(user).sort();
const expected = ['facebookId', 'firstName', 'isLoggedIn', 'lastName'];
expect(actual).toEqual(expected);
});
});
const name = { firstName: 'Hello', lastName: 'World' };
const facebook = { facebookId: 123 };
const isLoggedIn = { isLoggedIn: false };
const Name = (options = {}) => Object.assign({}, name, options);
const Facebook = (options = {}) => Object.assign({}, facebook, options);
const IsLoggedIn = (options = {}) => Object.assign({}, isLoggedIn, options);
export { IsLoggedIn, Facebook, Name };
/**
* TEST
*/
describe('Prototypal Inheritance', () => {
it('should have firstName and lastName', () => {
const name = {
firstName: 'Foo',
lastName: 'Bar'
};
const actual = Name(name);
const expected = {
...name
};
expect(actual).toEqual(expected);
});
it('should have facebookId', () => {
const options = {
facebookId: 'A1B2'
};
const actual = Facebook(options);
const expected = {
...options
};
expect(actual).toEqual(expected);
});
it('should have IsLoggedIn', () => {
const options = {
isLoggedIn: true
};
const actual = IsLoggedIn(options);
const expected = {
...options
};
expect(actual).toEqual(expected);
});
});