Урок 14: Прототипы
Прототипы являются важной частью объектно-ориентированного программирования в JavaScript. Они позволяют объектам наследовать свойства и методы других объектов. В этом уроке мы рассмотрим, как работают прототипы в JavaScript и как реализовать наследование через прототипы.
Понимание прототипов в JavaScript
Каждый объект в JavaScript имеет внутреннее свойство [[Prototype]]
, которое указывает на другой объект или null
. Этот другой объект называется прототипом. Когда вы пытаетесь получить доступ к свойству объекта, JavaScript сначала ищет это свойство в самом объекте, а затем в его прототипе, и так далее по цепочке прототипов.
// Создание объекта с прототипом
let person = {
greet: function() {
console.log('Hello!');
}
};
let student = Object.create(person);
student.study = function() {
console.log('Studying...');
};
student.greet(); // Hello!
student.study(); // Studying...
В этом примере объект student
наследует метод greet
от своего прототипа person
и имеет свой собственный метод study
.
Наследование через прототипы
Прототипное наследование позволяет одному объекту наследовать свойства и методы другого объекта. Это может быть достигнуто с помощью метода Object.create
или конструктора функций и свойства prototype
.
Использование Object.create
Метод Object.create
создает новый объект с указанным прототипом.
// Пример использования Object.create
let animal = {
speak: function() {
console.log('Animal makes a sound');
}
};
let dog = Object.create(animal);
dog.bark = function() {
console.log('Dog barks');
};
dog.speak(); // Animal makes a sound
dog.bark(); // Dog barks
Animal makes a sound
Dog barks
Использование конструктора функций и prototype
Конструкторы функций и свойство prototype
позволяют создавать объекты и настраивать их прототипы.
// Пример использования конструктора функций и prototype
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
let alice = new Person('Alice');
alice.greet(); // Hello, my name is Alice
В этом примере мы создали конструктор Person
и добавили метод greet
к его прототипу. Все объекты, созданные с помощью new Person
, будут наследовать этот метод.
Цепочка прототипов
Цепочка прототипов образует иерархию, по которой JavaScript ищет свойства и методы.
// Пример цепочки прототипов
let grandparent = {
sayHello: function() {
console.log('Hello from grandparent');
}
};
let parent = Object.create(grandparent);
parent.sayHello = function() {
console.log('Hello from parent');
};
let child = Object.create(parent);
child.sayHello(); // Hello from parent
В этом примере объект child
наследует метод sayHello
от объекта parent
, который в свою очередь наследует этот метод от объекта grandparent
.
Примеры использования прототипов
Рассмотрим несколько примеров использования прототипов в различных ситуациях.
// Пример 1: Добавление метода к встроенному объекту
Array.prototype.last = function() {
return this[this.length - 1];
};
let numbers = [1, 2, 3, 4];
console.log(numbers.last()); // 4
// Пример 2: Создание прототипной цепочки
function Shape() {
this.type = 'shape';
}
Shape.prototype.getType = function() {
return this.type;
};
function Circle(radius) {
Shape.call(this); // Вызов конструктора родителя
this.radius = radius;
}
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
Circle.prototype.getArea = function() {
return Math.PI * this.radius * this.radius;
};
let circle = new Circle(5);
console.log(circle.getType()); // shape
console.log(circle.getArea()); // 78.53981633974483
4
shape
78.53981633974483
Упражнения
Упражнение 1: Создание цепочки прототипов
Создайте объект vehicle
с методом move
, который выводит сообщение "Vehicle is moving". Затем создайте объект car
, который наследует vehicle
, и добавьте метод drive
, который выводит сообщение "Car is driving". Вызовите оба метода у объекта car
.
Решение:
// Создание объекта vehicle
let vehicle = {
move: function() {
console.log('Vehicle is moving');
}
};
// Создание объекта car, наследующего vehicle
let car = Object.create(vehicle);
car.drive = function() {
console.log('Car is driving');
};
car.move(); // Vehicle is moving
car.drive(); // Car is driving
Vehicle is moving
Car is driving
Объяснение: Мы создали объект vehicle
с методом move
и объект car
, который наследует vehicle
и имеет собственный метод drive
. Затем мы вызвали оба метода у объекта car
.
Упражнение 2: Расширение встроенного объекта
Добавьте метод first
к прототипу массива, который возвращает первый элемент массива. Создайте массив и вызовите этот метод.
Решение:
// Добавление метода first к прототипу массива
Array.prototype.first = function() {
return this[0];
};
let numbers = [10, 20, 30, 40];
console.log(numbers.first()); // 10
Объяснение: Мы добавили метод first
к прототипу массива, который возвращает первый элемент массива. Затем мы создали массив numbers
и вызвали этот метод, чтобы получить первый элемент массива.