Defining a constructor function Example of an object using object initialiation
const fellowshipOfTheRing = {
  title: "The Fellowship of the Ring",
  series: "The Lord of the Rings",
  author: "J.R.R. Tolkien",
};Object Type is defined by it’s attributes and behaviors.
Behaviors are represented by methods.Constructor Functions : Handle the creation of an object - it’s a factory for creating objects of a specific type.
function Book(title, series, author) {
  this.title = title;
  this.series = series;
  this.author = author;
}new keyword.function Book(title, series, author) {
  this.title = title;
  this.series = series;
  this.author = author;
}
const fellowshipOfTheRing = new Book(
  "The Fellowship of the Ring",
  "The Lord of the Rings",
  "J.R.R. Tolkien"
);
console.log(fellowshipOfTheRing); // Book { title: 'The Fellowship of the Ring', ... }prototype is set to the object referenced by the constructors prototype property.This is bound to the new object.Understanding New Object Instances
Instance : term to describe an objected created from a constructor function.Using the instanceof operator to check an object’s type
instanceof operator we can verify that an object was created from a certain object type.
Invoking a constructor function without the new keyword
new keyword, we may result in one of two unexpected outcomes:
strict mode, this will become undefined.
"use strict" at the top of your file.Defining Sharable Methods
Avoid the temptation to store an object method inside a constructor function, it is inefficient with computer memory usage b/c each object instance would have it’s own method definition.
Prototype : An object that is delegated to when a reference to an object property or method can’t be resolved.
Object.setPrototypeOf() and Object.getPrototypeOf() are just used to set a prototype of one object to another object; and also the verify a prototype.
proto : aka “dunder proto” is a property used to gain easy access to an object’s prototype - it is widely supported by browsers but is considered deprecated.function Book(title, series, author) {
  this.title = title;
  this.series = series;
  this.author = author;
}
// Any method defined on the `Book.prototype` property
// will be shared across all `Book` instances.
Book.prototype.getInformation = function () {
  return `${this.title} by ${this.author}`;
};
const fellowshipOfTheRing = new Book(
  "The Fellowship of the Ring",
  "The Lord of the Rings",
  "J.R.R. Tolkien"
);
console.log(fellowshipOfTheRing.getInformation());The Problem with Arrow Functions
In ES2015, JS gained the class keyword - replacing the need to use only constructor functions & prototypes to mimic classes!
class : keyword that gives developers a formal way to create a class definition to specify an object type’s attributes and behavior; also used to create objects of that specific type.Defining a ES2015 class
class Book {
  constructor(title, series, author) {
    this.title = title;
    this.series = series;
    this.author = author;
  }
}class constructor function - these are similar to regular constructors in that:
Instantiating an instance of a class
We can also use the new.
This is bound to the new object.Don’t try to instatiate a class object without the new keyword.
Class Definitions are NOT hoisted
hoisting.Defining Methods
A class can contain two types of methods:
Instance Method : Methods that are invoked on an instance of the class - useful for performing an action on a specific instance.
prototype methods because they are defined on a shared prototype object.Static Method : Methods that invoked directly on a class, not on an instance.
Important: Invoking a static method on an instance will result in a runtime error.static keyword at the beginning on the method name will make it static.class Book {
  constructor(title, series, author) {
    this.title = title;
    this.series = series;
    this.author = author;
  }
  // Notice the use of a rest parameter (...books)
  // to capture the passed parameters as an array of values.
  static getTitles(...books) {
    return books.map((book) => book.title);
  }
  getInformation() {
    return `${this.title} by ${this.author}`;
  }
}
const fellowshipOfTheRing = new Book(
  "The Fellowship of the Ring",
  "The Lord of the Rings",
  "J.R.R. Tolkien"
);
const theTwoTowers = new Book(
  "The Two Towers",
  "The Lord of the Rings",
  "J.R.R. Tolkien"
);
const bookTitles = Book.getTitles(fellowshipOfTheRing, theTwoTowers);
console.log(bookTitles.join(", ")); // The Fellowship of the Ring, The Two Towersfunction Book(title, series, author) {
  this.title = title;
  this.series = series;
  this.author = author;
}
// Static methods are defined
// directly on the constructor function.
Book.getTitles = function (...books) {
  return books.map((book) => book.title);
};
// Instance methods are defined
// on the constructor function's `prototype` property.
Book.prototype.getInformation = function () {
  return `${this.title} by ${this.author}`;
};
const fellowshipOfTheRing = new Book(
  "The Fellowship of the Ring",
  "The Lord of the Rings",
  "J.R.R. Tolkien"
);
const theTwoTowers = new Book(
  "The Two Towers",
  "The Lord of the Rings",
  "J.R.R. Tolkien"
);
console.log(fellowshipOfTheRing.getInformation()); // The Fellowship of the Ring by J.R.R. Tolkien
console.log(theTwoTowers.getInformation()); // The Two Towers by J.R.R. Tolkien
// Call the static `Book.getTitles()` method
// to get an array of the book titles.
const bookTitles = Book.getTitles(fellowshipOfTheRing, theTwoTowers);
console.log(bookTitles.join(", ")); // The Fellowship of the Ring, The Two TowersComparing Classes to Constructor Functions
ES2015 Classes are essentially syntactic sugar over traditional constructor functions and prototypes.
Child Class : Class that is based upon another class and inherits properties and methods from that other class.Parent Class : Class that is being inherited downwards.Inheritance : The process of basing a class upon another class.class CatalogItem {
  constructor(title, series) {
    this.title = title;
    this.series = series;
  }
  getInformation() {
    if (this.series) {
      return `${this.title} (${this.series})`;
    } else {
      return this.title;
    }
  }
}
class Book extends CatalogItem {
  constructor(title, series, author) {
    super(title, series);
    this.author = author;
  }
}
class Movie extends CatalogItem {
  constructor(title, series, director) {
    super(title, series);
    this.director = director;
  }
}
const theGrapesOfWrath = new Book(
  "The Grapes of Wrath",
  null,
  "John Steinbeck"
);
const aNewHope = new Movie(
  "Episode 4: A New Hope",
  "Star Wars",
  "George Lucas"
);
console.log(theGrapesOfWrath.getInformation()); // The Grapes of Wrath
console.log(aNewHope.getInformation()); // Episode 4: A New Hope (Star Wars)
console.log(Catalogitem instanceof Function); // true
console.log(Book instanceof Function); // trueA prototype chain defines a series of prototype objects that are delegated to one by one, when a property or method can’t be found on an instance object.
getInformation() method is invoked:
Overriding a method in a parent class
Method Overriding : when a child class provides an implementation of a method that’s already defined in a parent class.class Movie extends CatalogItem {
  constructor(title, series, director) {
    super(title, series);
    this.director = director;
  }
  getInformation() {
    let result = super.getInformation();
    if (this.director) {
      result += ` [directed by ${this.director}]`;
    }
    return result;
  }
}getInformation()Introducing Node.js modules
module.Local Modules : Modules defined within your project.Core Modules : Native modules contained within Node.js that you can use to perform tasks or to add functionality to your application.CommonJS : A legacy module system.ES Modules : Newer module sysem that will eventually replace CommonJS.
Entry Point : JS File that is passed to Node for access to the entire application.Syntax for exporting modules:
Syntax for importing modules:
Using Single Item Modules
Following the convention of a single exported item per module helps to keep modules focused and less likely to become bloted with too much code.
Understanding Module Loading
Local Module: identifier starts with ./ ../ or /Node.js Core: identifier matches nameThird-Party: identifier matches a module in the node modules folder (installed package)