# OOP in JavaScript ## Creating a JavaScript Object ### `Object.create` ```js function Book({name, author, year}) { const constructor = { getTitle: function() { return this.name + ' by ' + this.author + ' (' + this.year + ')'; } }; const book = Object.create(constructor); book.name = name; book.author = author; book.year = year; return book; } // test const lastBook = Book({ name: "Foundation and Earth", author: "Isaac Asimov", year: 1986 }); console.log(lastBook); // {name: 'Foundation and Earth', author: 'Isaac Asimov', year: 1986} console.log(lastBook.getTitle()); // Foundation and Earth by Isaac Asimov (1986) ``` ### `new` keyword > PROTOTYPE CHAINING, function object combination ```js function Book({name, author, year}) { this.name = name; this.author = author; this.year = year; } Book.prototype.getTitle = function() { return this.name + ' by ' + this.author + ' (' + this.year + ')'; }; // test const lastBook = new Book({ name: "Foundation and Earth", author: "Isaac Asimov", year: 1986 }) console.log(lastBook); // Book {name: 'Foundation and Earth', author: 'Isaac Asimov', year: 1986} console.log(lastBook.getTitle()); // Foundation and Earth by Isaac Asimov (1986) ``` ### `Class` (ECMAScript 2015) ```js class Book { constructor({name, author, year}) { this.name = name; this.author = author; this.year = year; } getTitle() { return this.name + ' by ' + this.author + ' (' + this.year + ')'; } } // test const lastBook = new Book({ name: "Foundation and Earth", author: "Isaac Asimov", year: 1986 }) console.log(lastBook); // Book {name: 'Foundation and Earth', author: 'Isaac Asimov', year: 1986} console.log(lastBook.getTitle()); // Foundation and Earth by Isaac Asimov (1986) ``` ## Subclassing ```js class BookInterface { constructor(author) { this.author = author; } getAuthor() { return this.author; } } class Book extends BookInterface { constructor({name, author, year}) { super(author); this.name = name; this.year = year; } getTitle() { return this.name + ' by ' + this.author + ' (' + this.year + ')'; } } // test const lastBook = new Book({ name: "Foundation and Earth", author: "Isaac Asimov", year: 1986 }) console.log(lastBook); // Book {name: 'Foundation and Earth', author: 'Isaac Asimov', year: 1986} console.log(lastBook.getTitle()); // Foundation and Earth by Isaac Asimov (1986) ``` ### Subclassing via `Object.create` > Object.setPrototypeOf ```js function BookInterface(author) { const constructor = { getAuthor: function() { return this.author; } }; const book = Object.create(constructor); book.author = author; return book; } function Book({name, author, year}) { const book = BookInterface(author); const constructor = { getTitle: function() { return this.name + ' by ' + this.author + ' (' + this.year + ')'; } }; Object.setPrototypeOf(book, constructor); book.name = name; book.year = year; return book; } // test const lastBook = new Book({ name: "Foundation and Earth", author: "Isaac Asimov", year: 1986 }); console.log(lastBook); // {name: 'Foundation and Earth', author: 'Isaac Asimov', year: 1986} console.log(lastBook.getTitle()); // Foundation and Earth by Isaac Asimov (1986) ``` ## JavaScript Class ```js class Book { #genre; constructor({ name, author, year, genre }) { this.name = name; this.author = author; this.year = year; this.#genre = genre; } static getInfo() { return 'Class: Book'; } getTitle() { return this.name + ' by ' + this.author + ' (' + this.year + ')'; } get() { return this.#getBook(); } getGanre() { return this.#genre; } #getBook() { return { ...this, }; } } // test const lastBook = new Book({ name: 'Foundation and Earth', author: 'Isaac Asimov', year: 1986, genre: 'sci-fi', }); console.log(Book.getInfo()); console.log(lastBook); console.log(lastBook.getTitle()); console.log(lastBook.get()); console.log(lastBook.getGanre()); ``` ### Singleton pattern ```js class Singleton{ constructor() { if (Singleton._instance) { Singleton._instance = this; } return Singleton._instance; } static getInstance() { return this._instance; } } ```