Posted January 24Jan 24 You are reading Part 24 of the 39-part series: JavaScript Skill Progression: The Path from Beginner to Extreme. [Level 4]JavaScript Prototypes, Inheritance, and Encapsulation: Prototype Chaining, Object.create(), Private Methods, and Classes in ES6IntroductionJavaScript uses prototypal inheritance, meaning objects can inherit properties and methods from other objects. This is done through prototype chaining, which forms the basis of object-oriented programming (OOP) in JavaScript. In modern JavaScript (ES6+), classes provide a more intuitive syntax for implementing inheritance and encapsulation.The Object.create() method facilitates direct prototype manipulation, while ES6 classes offer a cleaner, more intuitive syntax for implementing inheritance and encapsulation. Private fields in ES6 provide a robust way to protect data inside objects, while closures enable encapsulation in older JavaScript versions. Understanding these concepts is crucial for mastering JavaScript's object-oriented programming model.1. Understanding PrototypesEvery JavaScript object has an internal property called [[Prototype]], which points to another object known as its prototype. The prototype contains shared properties and methods that can be accessed by instances.Example of Prototype Inheritance:function Person(name, age) { this.name = name; this.age = age; } Person.prototype.greet = function() { console.log(`Hello, my name is ${this.name}.`); }; let alice = new Person("Alice", 25); alice.greet(); // Output: Hello, my name is Alice. The method greet() is not defined directly on alice, but alice inherits it from Person.prototype.If JavaScript cannot find a property on alice, it looks up the prototype chain to Person.prototype.2. Prototype ChainingPrototype chaining allows objects to inherit properties and methods from other objects up the chain.Example of Prototype Chain:function Animal(name) { this.name = name; } Animal.prototype.makeSound = function() { console.log("Some generic animal sound"); }; function Dog(name, breed) { Animal.call(this, name); this.breed = breed; } Dog.prototype = Object.create(Animal.prototype); // Establish prototype chain Dog.prototype.constructor = Dog; // Reset constructor Dog.prototype.bark = function() { console.log("Woof! Woof!"); }; let dog = new Dog("Buddy", "Golden Retriever"); dog.makeSound(); // Output: Some generic animal sound dog.bark(); // Output: Woof! Woof! Dog inherits from Animal using Object.create(Animal.prototype).The bark() method is unique to Dog, but Dog can still use makeSound() from Animal.3. Using Object.create() for Prototypal InheritanceThe Object.create() method creates a new object with a specified prototype.Example:let car = { drive() { console.log("Car is driving"); } }; let electricCar = Object.create(car); electricCar.charge = function() { console.log("Charging the electric car"); }; electricCar.drive(); // Output: Car is driving electricCar.charge(); // Output: Charging the electric car 4. ES6 Classes, Encapsulation, and Private MethodsES6 introduced the class syntax, making inheritance more readable and structured, along with mechanisms for encapsulation.Example Using ES6 Classes and Encapsulation:class Vehicle { constructor(type) { this.type = type; } drive() { console.log(`The ${this.type} is moving`); } } class Car extends Vehicle { #engineStatus = "off"; // Private field (ES6+) constructor(type, brand) { super(type); // Calls parent constructor this.brand = brand; } honk() { console.log("Beep! Beep!"); } startEngine() { this.#engineStatus = "on"; console.log("Engine started."); } getEngineStatus() { return this.#engineStatus; } } let myCar = new Car("car", "Tesla"); myCar.drive(); // Output: The car is moving myCar.honk(); // Output: Beep! Beep! myCar.startEngine(); // Output: Engine started. console.log(myCar.getEngineStatus()); // Output: on Car extends Vehicle, inheriting its properties and methods.#engineStatus is a private field, meaning it cannot be accessed outside the class directly.Encapsulation Using ClosuresClosures provide another way to implement encapsulation by hiding private data within function scopes.function createCounter() { let count = 0; return { increment() { count++; console.log("Count:", count); }, getCount() { return count; } }; } const counter = createCounter(); counter.increment(); // Output: Count: 1 console.log(counter.getCount()); // Output: 1 5. Differences Between Prototype-Based and Class-Based InheritanceFeaturePrototype-BasedClass-Based (ES6)Syntax ComplexityRequires manual setupMore intuitiveMethod DefinitionDefined on prototype explicitlyDefined inside the classInheritance SetupUses Object.create() or __proto__Uses extends and super()EncapsulationNot native, uses closuresSupports private fields (#field)ReadabilityLess readableMore structured and readableYou are reading Part 24 of the 39-part series: JavaScript Skill Progression: The Path from Beginner to Extreme. [Level 4]
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.