Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ivikash/c7ac2864a39bd6c3d1fbcf130ad7d685 to your computer and use it in GitHub Desktop.
Save ivikash/c7ac2864a39bd6c3d1fbcf130ad7d685 to your computer and use it in GitHub Desktop.
Difference b/w Classical Inheritance and Prototypal Inheritance in Javascript

Inheritance

Classical Inheritance

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.

Prototypal Inheritance

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.

Examples

Class Inheritance

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);
  });
});

Prototypal Inheritance

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);
  });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment