
3.1.1 Explanation of JavaScript's prototype-based inheritance model
In JavaScript, every object has an internal property called [[Prototype]] that points to another object. This object is known as its prototype. When you try to access a property or method on an object, JavaScript first looks at the object itself. If it doesn't find the property or method, it looks at the object's prototype, and so on, until it reaches null.
Example 1. How Prototype-Based Inheritance works. Direct method
The script creates an object named "solacida" that represents an acidic chemical solution.
This object inherits the "reactivo" property and the "reaccion()" method from the "test" prototype.
Then, the script displays information about solacida's properties in the console and on the web page
and executes the "reaccion()" method. The process evaluates
qualitatively if a solution changes the PH indicator color to red,
which indicates that it is acidic.
Direct Method
a) The inheritance approach used in this code is the most direct and common in JavaScript:
- Direct prototype assignment: The "test" object is explicitly assigned as the prototype of "solacida" using __proto__.
- Inheritance of properties and methods: The new "solacida" object inherits all properties and methods from its "test" prototype.
- Addition of specific properties: The "solacida" object can have its own additional properties and methods
that are not found in the prototype.
Algorithm Advantages
- Flexible: Allows modifying object behavior at runtime.
- Dynamic: Facilitates the creation of custom objects and the extension of existing ones.
- Object-based: Everything in JavaScript is an object, including prototypes.
Example 2. Creating a prototype with the Object.create method
This approach uses the Object.create() method to
create a new object that inherits directly from the specified prototype.
It is an explicit and direct way to establish inheritance in JavaScript.
Main Characteristics:
- Explicit prototype: With Object.create(), it is explicitly defined
that the new object inherits from a specific prototype.
- No constructors: This approach does not use constructors. Instead,
objects are created directly.
- Direct prototype configuration: The new object is connected to its
base prototype (baby in this case), but there is no "constructor function"
that initializes dynamic properties.
Algorithm Advantages:
- Simple and clear for establishing prototypical relationships.
- Ideal for simple objects or shallow hierarchies.
Example 3. Inheritance with Constructor Functions and "new"
In this approach, a constructor function is defined to set
unique properties per instance, and the "prototype" property is used to define shared methods.
Then, the function is called with new to create instances.
Main Characteristics
- Use of constructor functions: Each "class" is represented by a function
that initializes specific properties for each instance.
- Shared methods on the prototype: Methods that should be shared
by all instances are defined on the prototype property.
- Inheritance via Object.create(): The prototype of the child constructor (Congelador)
is connected to the prototype of the parent constructor (Camara) using Object.create().
Advantages
- Supports initialization of unique properties per instance via the
constructor function.
- Compatible with the classic instance creation pattern using new,
which is more familiar to programmers coming from object-oriented languages
like Java or C#.
- Scalable for more complex hierarchies and class relationships.
3.1.2. Class-Based Inheritance in JavaScript
Example 1. Class-Based Inheritance
The code demonstrates how class-based inheritance works in JavaScript. The "Nave" class extends the functionality of the "Flight" class, creating a class hierarchy. An object of the "Nave" class can access both the properties and methods inherited from "Flight" as well as its own properties and methods.
3.1.3 Concept of the Prototype Chain
Example 1. Demonstrating how the prototype chain works
The prototype chain is a powerful mechanism in JavaScript
that allows for the creation of complex and reusable objects. By understanding how it works,
we can write more efficient and flexible code.
Let's study how it works in this example.
- Creation of the prototype: An object called deportista is created to serve as
a prototype for other objects.
- Creation of an inheriting object: An object called entrenándose is created
that inherits from deportista using Object.create. This means that entrenándose
has access to all methods and properties of deportista.
- Adding specific properties and methods: A new method called
correr is added to the entrenándose object.
- Creation of another inheriting object: A novato object is created that inherits
from entrenándose; therefore, it also inherits from deportista.
- Access to properties and methods: When accessing novato.saludar(),
JavaScript first looks in novato, then in entrenándose (its prototype),
and finally in deportista where it finds the method.
Prototype Chain Visualization
novato > entrenándose > deportista > Object.prototype > null
3.2 Differences between `__proto__`, `Object.getPrototypeOf()` and `prototype` properties.
3.2.1 The __proto__ Property. Confirms the prototype of an Object instance
Example 1. Checking an object's prototype
Example 2. Creating a new object and setting its prototype using __proto__
Fundamental Characteristics:
- Direct prototype access: It is a property that points directly to an object's prototype object.
- Concise syntax: Its syntax is simple and direct.
- Modifiable: Although it is possible to modify __proto__, it is not recommended because it can lead to
unexpected behavior and make the code less maintainable.
- Non-standard: Although widely used, __proto__ is not
fully standardized and its behavior may vary across different browsers.
3.2.2. Object.getPrototypeOf() Property. Obtaining the prototype of a specific Object
Example 1. Object.getPrototypeOf() Property
Object.getPrototypeOf() is a predefined function in JavaScript
that allows you to get the prototype of a specific object. In simpler terms,
it tells us from which other object a given object "inherits" its properties and methods.
In the completed example, it informs us from which other object (in the example, the "auto" object) the "Ford" instance
"inherits" its properties and methods.
Qualities::
- Standard method: It is a method of the Object object used
to obtain an object's prototype safely and standardly.
- Indirect access: Returns a reference to the prototype but does not allow
modifying it directly.
- Recommended: It is the recommended way to access an object's prototype,
as it is more secure and compatible.
3.2.3. The prototype Property. Confirms which prototype an Object instance belongs to, returning true or false.
Example 1. Using the prototype property
prototype Property
Constructor property: It is a property of constructor functions used
to specify the prototype that will be assigned to objects created
from that function.
!prototype is not the same as __proto__!.
prototype refers to the prototype that will be used to create new objects,
while __proto__ points to the prototype of an existing object.
3.2.4. What we understand by the base object Object.prototype
Example 1. Extending the "activar" method
Object.prototype
It is the most basic object and serves as a prototype for all other objects in JavaScript.
This means that all objects inherit properties and methods from Object.prototype.
Example 2. Adding the "laMayorPotencia" property to all equipment that has the "potencia" property
In JavaScript, searching for properties in the prototype
chain is a fundamental process for prototypical inheritance.
In section 3.1.3, through a practical exercise, it was demonstrated how
the prototype chain works in JavaScript. A 'deportista' object was created
that served as a prototype for a new 'novato' object,
which inherited its characteristics and behaviors.
3.3. Modifying the prototype using `Object.setPrototypeOf()`
Exercise 1. Changing the prototype using Object.setPrototypeOf
Code Description:
a) The code begins by defining two objects: "águila" and "cisne". Each has a unique property:
- águila: Has the "eats" property with the value "YES. Already fed".
- cisne: Has the "flight" property with the value "does not fly".
b) Inheritance via Object.setPrototypeOf
The key line is Object.setPrototypeOf(cisne, águila).
This line sets the "águila" object as the prototype of the "cisne" object.
This means that the "cisne" object will inherit properties and methods
from the "águila" object if it does not have them defined itself.
3.3.3. Difference between `Object.create()` and object literal notation (`{}`).
Example 1. Using object literal notation {}
Example 2. Using Object.create()
Object literal notation is simpler and more direct for creating basic objects, while Object.create() offers greater flexibility by allowing the specification of the object's prototype.
Calls to the presentar() and entregar() methods
Invoking the "sección" property of the Plano constructor
Accessing the Plano constructor and the native constructor.
3.5. Prototypes and Native JavaScript Methods
Due to the volume of output generated by executing these scripts,
we will only print their results to the browser console, omitting
them from the local browser view.
The scripts for these exercises are found in Chapter 3 of
Book 3 "Programming Step by Step and More".
Exercise 1. Array Methods
Exercise 2. String Methods
Exercise 3. Number Methods
Exercise 4. Date Methods