SlideShare a Scribd company logo
1 of 32
Download to read offline
Объектное, прототипно-
ориентированное
программирование
Курс Frontend-разработки на Javascript + Vue/React
Задача 0.
• Создать массив объектов – товаров. У каждого товара есть название, цена,
масса. Создать не менее 6 товаров.
• Создать объект Склад. У склада есть метод извлечения товара – он
принимает название, цену товара и возвращает объект товара с
указанными названием и ценой и случайной массой.
• Создать два объекта Магазин. В магазине есть название, также в нем
хранится массив товаров, есть метод для добавления товара и очистки
магазина. В магазине есть метод, возвращающий общую стоимость всех
товаров в магазине.
• Создать 6 товаров с использованием Склада. Распределить созданные
товары по двум магазинам. Вызвать методы подсчета стоимости товаров в
магазинах и вывести их результат в консоль.
Защита объектов
• Защита объектов – специальный приём, позволяющий для
некоторого объект предотвратить использование на нём
модифицирующих операций.
Уровни защиты объектов
const item = { /* Object content */}
Object.preventExtensions(item);
// Запрет расширения.
// В объект больше нельзя добавить новые свойства.
Object.seal(item);
// Запечатывание. Включает запрет расширения.
// Из объекта нельзя удалить существующие свойства
Object.freeze(item);
// Заморозка. Включает запечатывание.
// В объекте нельзя изменить значение существующих свойств
Добавление свойств при помощи
дескрипторов
• Создавать новые свойства в объекте можно путем простого
присваивания новому полю значения:
• Тем не менее, в Javascript объекты и их свойства обладают более
гибким функционалом. Создавать свойства можно при помощи
дескрипторов – этот подход позволит настроить уровни доступа к
полю такого объекта.
const item = { /* Object content */};
item.x = 10;
DefineProperty
• При создании свойства
через defineProperty в
объекте дескрипторов
указываются поля,
отвечающие за различные
уровни доступа к этому
полю.
const item = { /* Object content */};
Object.defineProperty(item, 'x', {
// Descriptors
})
Object.defineProperty(item, 'x', {
value: 10,
writable: true,
configurable: false,
enumerable: true,
})
Дескрипторы
Дескриптор Значение Описание
value any Значение в поле
enumerable true|false Если задано false, то поле не будет участвовать в
обходе объекта циклом for..in
configurable true|false Если задано false, то поле нельзя удалить
оператором delete и изменить дескрипторы
writable true|false Если задано false, то полю нельзя задать другое
значение
set function Если задана функция, то она будет вызываться в
случаях, когда в поле присваивается новое значение
get function Если задана функция, то она будет вызываться в
случаях, когда значение поля вызывается для чтения.
Несовместимо с дескриптором value.
Вычисляемые свойства
const point = {
x: 3,
y: 4
};
Object.defineProperty(point, 'distance', {
get() {
return (this.x ** 2 + this.y ** 2) ** (1 / 2);
},
set(value) {
this.x = value;
this.y = 0;
}
})
console.log(point.distance); // 5
point.distance = 10;
console.log(point); // {x: 10, y: 0}
Задача 1.
• Создать объект человека. У него в полях есть имя и год рождения.
• Создать свойство «возраст». При чтении оно вернет возраст
человека в годах. При записи оно поменяет год рождения человека
так, чтобы тот соответствовал переданному возрасту.
Прокси-объекты
• Прокси-объектом называется объект специального рода, который
замещает собой некоторый оригинальный объект и осуществляет
предварительную обработку всех операций, направляемых на
объект.
Proxy ОбъектСкрипт
Создание Proxy
• Прокси-объект как бы
подменяет собой
оригинальный. Далее вся
работа в скрипте
осуществляется только через
этот прокси-объект.
• В объекте с handlers
описываются методы-ловушки,
реагирующие на действия с
объектом-прокси.
const originalPoint = {
x: 10,
y: 20,
}
const point = new Proxy(originalPoint, {
// Action handlers
});
console.log(point.x); // 10
Ловушки (handlers) Proxy
const point = new Proxy(originalPoint, {
get(target, prop, receiver) {
if (prop in target) {
return target[prop];
}
return 'Prop not found!';
}
});
console.log(point.x); // 10
console.log(point.z); // "Prop not found!"
const point = new Proxy(originalPoint, {
set(target, prop, value, receiver) {
if(typeof value !== 'number') {
return false;
}
if(value < 0) {
value = 0;
}
target[prop] = value;
return true;
}
});
point.x = 10; // 10
point.x = -10; // 0
point.x = '10'; // 0
Типы ловушек
Тип Описание
get Вызывается, когда из прокси читается какое-либо свойство
set Вызывается, когда в прокси задается какое-либо свойство
has Вызывается, когда на прокси применяется оператор in
deleteProperty Вызывается, когда на прокси вызывается оператор delete
apply Вызывается, когда на прокси вызывается оператор () – вызов как функцию
construct Вызов на прокси оператора new.
… Дополнительные ловушки, связанные с объектной обработкой прокси
В одном прокси-объекте может быть по одной ловушке каждого типа.
Если ловушка отсутствует, то соответствующая операция
пробрасывается мимо прокси на проксируемый объект.
Задача 2.
• Создать прокси на объект человека. Не позволять создавать новые
поля, а при записи года человеку проверять, чтобы он был не в
будущем и не более чем на 120 лет в прошлом. Если эти условия не
соблюдаются, оставлять текущий год рождения.
Объектно-ориентированное
программирование в Javascript
• В Javascript нет как таковой целостной ОО-парадигмы. Тем не
менее, используются различные особенности Javascript для
реализации возможностей ООП.
Базовые принципы ООП
• Классом называется инструкция, по которой происходит создание новых
объектов того или иного типа.
• В ООП класс – базовая структурная единица. Объекты, создаваемые в ОО-
приложении, всегда относятся к какому-то классу.
• Тот факт, что объект относится к какому-то классу, позволяет четко
понимать, какие поля и методы он в себе содержит и как можно с ними
работать.
• В ОО-приложении весь код строится на взаимодействии некоторых
строго определенных в классах сущностей. Это позволяет искусственно
сжать круг возможностей в коде до четко определенного набора
операций и ошибиться становится сложнее.
Создание класса в Javascript
• Для создания классов используются три паттерна:
• Фабрика (генератор объектов)
• Конструктор
• Прототип
• Кроме того, в ES6 появился синтаксический сахар для работы с
ООП. Но он, по сути, является комбинацией паттерна Конструктор +
прототип.
Паттерн Фабрика
function Human(name, age) {
return {
name: name,
age: age,
getBirthYear() {
return (new Date).getFullYear() - this.age;
}
};
}
const man = Human('Alex', 30);
console.log(man); //{name: 'Alex', age: 30, getBirthYear: f}
Паттерн Конструктор
function Human(name, age) {
this.name = name;
this.age = age;
this.getBirthYear = function () {
return (new Date).getFullYear() - this.age;
}
}
const man = new Human('Alex', 30);
console.log(man); //{name: 'Alex', age: 30, getBirthYear: f}
Паттерн Прототип
function Human(name, age) {
this.name = name;
this.age = age;
}
Human.prototype.getBirthYear = function() {
return (new Date).getFullYear() - this.age;
}
const man = new Human('Alex', 30);
console.log(man); //{name: 'Alex', age: 30}
console.log(man.getBirthYear()); // 2000
Сравнение паттернов
• Паттерн Фабрика – самый простой паттерн. Но он не позволяет
реализовать наследование, не позволяет узнать, к какому классу
относится созданный объект.
• Паттерн Конструктор позволяет реализовать наследование и узнать
порождающий класс. Однако в нём создаются дубликаты методов.
• Паттерн Прототип расширяет конструктор, позволяя вынести
общие для всех экземпляров класса методы и свойства в одну точку
без дублирования.
Порождающий конструктор
• У объекта, созданного при помощи конструктора, существует
свойство constructor, которое ссылается на функцию-конструктор, с
помощью которой был создан объект.
• Оператор instanceof принимает в себя объект и функцию и
возвращает true, если объект был создан при помощи этой
функции-конструктора.
const man = new Human('Alex', 30);
console.log(man.constructor); // Human
console.log(man instanceof Human); // true
Задача 3.
• Создать класс Студент. У студента есть имя, курс, массив оценок за
курс. У студента есть метод получения его среднего балла.
• Создать класс Факультет. У факультета есть название и массив
обучающихся студентов. Создать метод зачисления студента на
факультет. Создать метод, который вернет средний балл всех
студентов на факультете.
• Создать 4 объекта класса Студент и один факультет. Зачислить
студентов на факультет, вывести средний балл всех студентов в
факультете.
Собственные свойства
• Собственными для объекта называются свойства, созданные
напрямую в конструкторе либо добавленные в этот объект вручную.
• Несобственными будут свойства, доступные в этом объекте, но
находящиеся в прототипе.
function X() {
this.a = 10;
this.b = 20;
}
X.prototype.c = 30;
X.prototype.d = 40;
const x = new X();
console.log(x.a, x.b, x.c, x.d);
Установка наличия свойства
• Оператор in вернет true
если свойство в
принципе доступно в
объекте – не важно,
собственное или нет.
• Метод hasOwnProperty у
любого объекта вернет
true только если
переданное в него
свойство является
собственным.
function X() {
this.a = 10;
this.b = 20;
}
X.prototype.c = 30;
X.prototype.d = 40;
const x = new X();
console.log(x.a, x.b, x.c, x.d);
console.log('a' in x); // true
console.log('d' in x); // true
console.log(x.hasOwnProperty('b')) // true
console.log(x.hasOwnProperty('c')) // false
Переопределение прототипа
• Свойство constructor, присутствующее у
объектов, является несобственным
(прототипным).
• Если в коде Вы перезаписываете прототип
полностью (а не дописываете), то
необходимо дополнить прототип
свойством constructor вручную (см.
пример)
function X() {
this.a = 10;
}
X.prototype = {
constructor: X,
getA() {},
getB() {},
getC() {}
}
Расширение базового прототипа
• Иногда можно встретить подход, расширяющий возможности
встроенных объектов, например:
• Этот подход наделяет базовые объекты новыми возможностями.
• Однако использовать такой подход сегодня не принято – он
существенно ухудшает читаемость кода и ослабляет устойчивость
кода.
const arr = [10, 20, 30];
Array.prototype.sum = function() {
return this.reduce((s, v) => s + v, 0);
}
console.log(arr.sum()); // 60
Прототипное наследование
function Car(model) {
this.model = model;
}
Car.prototype.drive = function () {
console.log('Dr-dr-dr-dr-dr');
}
function AmbulanceCar(model, capacity) {
Car.apply(this, [model]);
// or Car.call(this, model);
this.capacity = capacity;
}
AmbulanceCar.prototype = Object.create(Car.prototype);
AmbulanceCar.prototype.alert = function () {
console.log('Whe-o-whe-o-whe-o');
}
const car = new Car('Volvo');
car.drive();
const ambulance =
new AmbulanceCar('Volvo', 4);
ambulance.drive();
ambulance.alert();
Статические методы
• Статическими методами называются методы, которые относятся ко
всему классу целиком, а не только к экземпляру.
function Car(model) {
this.model = model;
Car.amount ++;
}
Car.amount = 0;
Car.printAmount = function() {
console.log(this.amount);
}
const cars = [new Car('BMV'), new Car('Volvo'), new Car('Porshe')];
Car.printAmount();
Классы в ES6
class Car {
model = '';
static amount = 0;
constructor(model) {
this.model = model;
Car.amount++;
}
drive() {
console.log('Dr-r-r-r-r-r')
}
static printAmount() {
console.log(this.amount);
}
}
Наследование ES6
class AmbulanceCar extends Car {
constructor(model, capacity) {
super(model);
this.capacity = capacity;
}
alert() {
console.log('Whe-o-whe-o');
}
}
Дополнительные материалы
Object.seal
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Gl
obal_Objects/Object/seal
Создание свойств с дескрипторами
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Gl
obal_Objects/Object/defineProperty
Proxy - простые примеры
https://habr.com/ru/company/ruvds/blog/359060/
Proxy - описание на MDN
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Gl
obal_Objects/Proxy
Proxy - описание на learn.javascript.ru
https://learn.javascript.ru/proxy
Прототипы
https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%
D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_proto
types
Введение в ООП
https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%
D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object-
oriented_JS
Прототипное наследование
https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%
D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Inheritance
ООП в ES6
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Cl
asses

More Related Content

What's hot

Лекция 5. Встроенные коллекции и модуль collections.
Лекция 5. Встроенные коллекции и модуль collections.Лекция 5. Встроенные коллекции и модуль collections.
Лекция 5. Встроенные коллекции и модуль collections.Roman Brovko
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4 Dima Dzuba
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Roman Brovko
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка DjangoVladimir Rudnyh
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Dima Dzuba
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Dima Dzuba
 
Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Roman Brovko
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILRoman Brovko
 
Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Roman Brovko
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)Smolensk Computer Science Club
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт GuavaEgor Chernyshev
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Dima Dzuba
 
Лекция 7. Исключения и менеджеры контекста.
Лекция 7. Исключения и менеджеры контекста.Лекция 7. Исключения и менеджеры контекста.
Лекция 7. Исключения и менеджеры контекста.Roman Brovko
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonPython Meetup
 
AlgoCollections (RUS)
AlgoCollections (RUS)AlgoCollections (RUS)
AlgoCollections (RUS)Anton Bukov
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Яковенко Кирилл
 

What's hot (20)

Decorators' recipes
Decorators' recipesDecorators' recipes
Decorators' recipes
 
Лекция 5. Встроенные коллекции и модуль collections.
Лекция 5. Встроенные коллекции и модуль collections.Лекция 5. Встроенные коллекции и модуль collections.
Лекция 5. Встроенные коллекции и модуль collections.
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка Django
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8.
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10
 
Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GIL
 
Funny JS #2
Funny JS #2Funny JS #2
Funny JS #2
 
Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)
 
Charming python sc2-8
Charming python sc2-8Charming python sc2-8
Charming python sc2-8
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт Guava
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
 
Лекция 7. Исключения и менеджеры контекста.
Лекция 7. Исключения и менеджеры контекста.Лекция 7. Исключения и менеджеры контекста.
Лекция 7. Исключения и менеджеры контекста.
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки Python
 
AlgoCollections (RUS)
AlgoCollections (RUS)AlgoCollections (RUS)
AlgoCollections (RUS)
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3
 

Similar to Объектное и прототипное программирование в Javascript

Ecma script 6 in action
Ecma script 6 in actionEcma script 6 in action
Ecma script 6 in actionYuri Trukhin
 
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий solit
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаAlexander Kucherenko
 
Выжить с помощью ООП. Максим Гопей
Выжить с помощью ООП. Максим ГопейВыжить с помощью ООП. Максим Гопей
Выжить с помощью ООП. Максим ГопейEatDog
 
Объекты в ECMAScript | Odessa Frontend Meetup #16
Объекты в ECMAScript | Odessa Frontend Meetup #16Объекты в ECMAScript | Odessa Frontend Meetup #16
Объекты в ECMAScript | Odessa Frontend Meetup #16OdessaFrontend
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловGeeksLab Odessa
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java scriptViktor Andreev
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Vasya Petrov
 
C# Desktop. Занятие 03.
C# Desktop. Занятие 03.C# Desktop. Занятие 03.
C# Desktop. Занятие 03.Igor Shkulipa
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3Technopark
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияYandex
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуAndreyGeonya
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Javametaform
 
C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.Igor Shkulipa
 
Михаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияМихаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияYandex
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxYandex
 

Similar to Объектное и прототипное программирование в Javascript (20)

Ecma script 6 in action
Ecma script 6 in actionEcma script 6 in action
Ecma script 6 in action
 
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий Solit 2014, EcmaScript 6 in Action, Трухин Юрий
Solit 2014, EcmaScript 6 in Action, Трухин Юрий
 
Survive with OOP
Survive with OOPSurvive with OOP
Survive with OOP
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языка
 
Выжить с помощью ООП. Максим Гопей
Выжить с помощью ООП. Максим ГопейВыжить с помощью ООП. Максим Гопей
Выжить с помощью ООП. Максим Гопей
 
Объекты в ECMAScript | Odessa Frontend Meetup #16
Объекты в ECMAScript | Odessa Frontend Meetup #16Объекты в ECMAScript | Odessa Frontend Meetup #16
Объекты в ECMAScript | Odessa Frontend Meetup #16
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java script
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
C# Desktop. Занятие 03.
C# Desktop. Занятие 03.C# Desktop. Занятие 03.
C# Desktop. Занятие 03.
 
Kotlin
KotlinKotlin
Kotlin
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знания
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногу
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Java
 
C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.C++ Базовый. Занятие 05.
C++ Базовый. Занятие 05.
 
Михаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияМихаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знания
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajax
 

More from Denis Latushkin

Дополнительные возможности Javascript
Дополнительные возможности JavascriptДополнительные возможности Javascript
Дополнительные возможности JavascriptDenis Latushkin
 
Дополнительные приёмы работы в DOM
Дополнительные приёмы работы в DOMДополнительные приёмы работы в DOM
Дополнительные приёмы работы в DOMDenis Latushkin
 
Отладка веб-приложений на Javascript
Отладка веб-приложений на JavascriptОтладка веб-приложений на Javascript
Отладка веб-приложений на JavascriptDenis Latushkin
 
Нестатичное позиционирование и верстка форм
Нестатичное позиционирование и верстка формНестатичное позиционирование и верстка форм
Нестатичное позиционирование и верстка формDenis Latushkin
 
Приёмы верстки страниц с использованием HTML + CSS
Приёмы верстки страниц с использованием HTML + CSSПриёмы верстки страниц с использованием HTML + CSS
Приёмы верстки страниц с использованием HTML + CSSDenis Latushkin
 
Габаритные свойства, блочная модель и псевдоэлементы CSS
Габаритные свойства, блочная модель и псевдоэлементы CSSГабаритные свойства, блочная модель и псевдоэлементы CSS
Габаритные свойства, блочная модель и псевдоэлементы CSSDenis Latushkin
 
Основы работы с таблицами стилей CSS
Основы работы с таблицами стилей CSSОсновы работы с таблицами стилей CSS
Основы работы с таблицами стилей CSSDenis Latushkin
 
Продвинутый HTML
Продвинутый HTMLПродвинутый HTML
Продвинутый HTMLDenis Latushkin
 
Основы работы с Git
Основы работы с GitОсновы работы с Git
Основы работы с GitDenis Latushkin
 
NPM и модульная архитектура приложения
NPM и модульная архитектура приложенияNPM и модульная архитектура приложения
NPM и модульная архитектура приложенияDenis Latushkin
 
Основы языка HTML
Основы языка HTMLОсновы языка HTML
Основы языка HTMLDenis Latushkin
 
Введение во фронтенд-разработку
Введение во фронтенд-разработкуВведение во фронтенд-разработку
Введение во фронтенд-разработкуDenis Latushkin
 
Использование сторонних библиотек в веб-приложении
Использование сторонних библиотек в веб-приложенииИспользование сторонних библиотек в веб-приложении
Использование сторонних библиотек в веб-приложенииDenis Latushkin
 
Приемы верстки страниц
Приемы верстки страницПриемы верстки страниц
Приемы верстки страницDenis Latushkin
 

More from Denis Latushkin (14)

Дополнительные возможности Javascript
Дополнительные возможности JavascriptДополнительные возможности Javascript
Дополнительные возможности Javascript
 
Дополнительные приёмы работы в DOM
Дополнительные приёмы работы в DOMДополнительные приёмы работы в DOM
Дополнительные приёмы работы в DOM
 
Отладка веб-приложений на Javascript
Отладка веб-приложений на JavascriptОтладка веб-приложений на Javascript
Отладка веб-приложений на Javascript
 
Нестатичное позиционирование и верстка форм
Нестатичное позиционирование и верстка формНестатичное позиционирование и верстка форм
Нестатичное позиционирование и верстка форм
 
Приёмы верстки страниц с использованием HTML + CSS
Приёмы верстки страниц с использованием HTML + CSSПриёмы верстки страниц с использованием HTML + CSS
Приёмы верстки страниц с использованием HTML + CSS
 
Габаритные свойства, блочная модель и псевдоэлементы CSS
Габаритные свойства, блочная модель и псевдоэлементы CSSГабаритные свойства, блочная модель и псевдоэлементы CSS
Габаритные свойства, блочная модель и псевдоэлементы CSS
 
Основы работы с таблицами стилей CSS
Основы работы с таблицами стилей CSSОсновы работы с таблицами стилей CSS
Основы работы с таблицами стилей CSS
 
Продвинутый HTML
Продвинутый HTMLПродвинутый HTML
Продвинутый HTML
 
Основы работы с Git
Основы работы с GitОсновы работы с Git
Основы работы с Git
 
NPM и модульная архитектура приложения
NPM и модульная архитектура приложенияNPM и модульная архитектура приложения
NPM и модульная архитектура приложения
 
Основы языка HTML
Основы языка HTMLОсновы языка HTML
Основы языка HTML
 
Введение во фронтенд-разработку
Введение во фронтенд-разработкуВведение во фронтенд-разработку
Введение во фронтенд-разработку
 
Использование сторонних библиотек в веб-приложении
Использование сторонних библиотек в веб-приложенииИспользование сторонних библиотек в веб-приложении
Использование сторонних библиотек в веб-приложении
 
Приемы верстки страниц
Приемы верстки страницПриемы верстки страниц
Приемы верстки страниц
 

Объектное и прототипное программирование в Javascript

  • 2. Задача 0. • Создать массив объектов – товаров. У каждого товара есть название, цена, масса. Создать не менее 6 товаров. • Создать объект Склад. У склада есть метод извлечения товара – он принимает название, цену товара и возвращает объект товара с указанными названием и ценой и случайной массой. • Создать два объекта Магазин. В магазине есть название, также в нем хранится массив товаров, есть метод для добавления товара и очистки магазина. В магазине есть метод, возвращающий общую стоимость всех товаров в магазине. • Создать 6 товаров с использованием Склада. Распределить созданные товары по двум магазинам. Вызвать методы подсчета стоимости товаров в магазинах и вывести их результат в консоль.
  • 3. Защита объектов • Защита объектов – специальный приём, позволяющий для некоторого объект предотвратить использование на нём модифицирующих операций.
  • 4. Уровни защиты объектов const item = { /* Object content */} Object.preventExtensions(item); // Запрет расширения. // В объект больше нельзя добавить новые свойства. Object.seal(item); // Запечатывание. Включает запрет расширения. // Из объекта нельзя удалить существующие свойства Object.freeze(item); // Заморозка. Включает запечатывание. // В объекте нельзя изменить значение существующих свойств
  • 5. Добавление свойств при помощи дескрипторов • Создавать новые свойства в объекте можно путем простого присваивания новому полю значения: • Тем не менее, в Javascript объекты и их свойства обладают более гибким функционалом. Создавать свойства можно при помощи дескрипторов – этот подход позволит настроить уровни доступа к полю такого объекта. const item = { /* Object content */}; item.x = 10;
  • 6. DefineProperty • При создании свойства через defineProperty в объекте дескрипторов указываются поля, отвечающие за различные уровни доступа к этому полю. const item = { /* Object content */}; Object.defineProperty(item, 'x', { // Descriptors }) Object.defineProperty(item, 'x', { value: 10, writable: true, configurable: false, enumerable: true, })
  • 7. Дескрипторы Дескриптор Значение Описание value any Значение в поле enumerable true|false Если задано false, то поле не будет участвовать в обходе объекта циклом for..in configurable true|false Если задано false, то поле нельзя удалить оператором delete и изменить дескрипторы writable true|false Если задано false, то полю нельзя задать другое значение set function Если задана функция, то она будет вызываться в случаях, когда в поле присваивается новое значение get function Если задана функция, то она будет вызываться в случаях, когда значение поля вызывается для чтения. Несовместимо с дескриптором value.
  • 8. Вычисляемые свойства const point = { x: 3, y: 4 }; Object.defineProperty(point, 'distance', { get() { return (this.x ** 2 + this.y ** 2) ** (1 / 2); }, set(value) { this.x = value; this.y = 0; } }) console.log(point.distance); // 5 point.distance = 10; console.log(point); // {x: 10, y: 0}
  • 9. Задача 1. • Создать объект человека. У него в полях есть имя и год рождения. • Создать свойство «возраст». При чтении оно вернет возраст человека в годах. При записи оно поменяет год рождения человека так, чтобы тот соответствовал переданному возрасту.
  • 10. Прокси-объекты • Прокси-объектом называется объект специального рода, который замещает собой некоторый оригинальный объект и осуществляет предварительную обработку всех операций, направляемых на объект. Proxy ОбъектСкрипт
  • 11. Создание Proxy • Прокси-объект как бы подменяет собой оригинальный. Далее вся работа в скрипте осуществляется только через этот прокси-объект. • В объекте с handlers описываются методы-ловушки, реагирующие на действия с объектом-прокси. const originalPoint = { x: 10, y: 20, } const point = new Proxy(originalPoint, { // Action handlers }); console.log(point.x); // 10
  • 12. Ловушки (handlers) Proxy const point = new Proxy(originalPoint, { get(target, prop, receiver) { if (prop in target) { return target[prop]; } return 'Prop not found!'; } }); console.log(point.x); // 10 console.log(point.z); // "Prop not found!" const point = new Proxy(originalPoint, { set(target, prop, value, receiver) { if(typeof value !== 'number') { return false; } if(value < 0) { value = 0; } target[prop] = value; return true; } }); point.x = 10; // 10 point.x = -10; // 0 point.x = '10'; // 0
  • 13. Типы ловушек Тип Описание get Вызывается, когда из прокси читается какое-либо свойство set Вызывается, когда в прокси задается какое-либо свойство has Вызывается, когда на прокси применяется оператор in deleteProperty Вызывается, когда на прокси вызывается оператор delete apply Вызывается, когда на прокси вызывается оператор () – вызов как функцию construct Вызов на прокси оператора new. … Дополнительные ловушки, связанные с объектной обработкой прокси В одном прокси-объекте может быть по одной ловушке каждого типа. Если ловушка отсутствует, то соответствующая операция пробрасывается мимо прокси на проксируемый объект.
  • 14. Задача 2. • Создать прокси на объект человека. Не позволять создавать новые поля, а при записи года человеку проверять, чтобы он был не в будущем и не более чем на 120 лет в прошлом. Если эти условия не соблюдаются, оставлять текущий год рождения.
  • 15. Объектно-ориентированное программирование в Javascript • В Javascript нет как таковой целостной ОО-парадигмы. Тем не менее, используются различные особенности Javascript для реализации возможностей ООП.
  • 16. Базовые принципы ООП • Классом называется инструкция, по которой происходит создание новых объектов того или иного типа. • В ООП класс – базовая структурная единица. Объекты, создаваемые в ОО- приложении, всегда относятся к какому-то классу. • Тот факт, что объект относится к какому-то классу, позволяет четко понимать, какие поля и методы он в себе содержит и как можно с ними работать. • В ОО-приложении весь код строится на взаимодействии некоторых строго определенных в классах сущностей. Это позволяет искусственно сжать круг возможностей в коде до четко определенного набора операций и ошибиться становится сложнее.
  • 17. Создание класса в Javascript • Для создания классов используются три паттерна: • Фабрика (генератор объектов) • Конструктор • Прототип • Кроме того, в ES6 появился синтаксический сахар для работы с ООП. Но он, по сути, является комбинацией паттерна Конструктор + прототип.
  • 18. Паттерн Фабрика function Human(name, age) { return { name: name, age: age, getBirthYear() { return (new Date).getFullYear() - this.age; } }; } const man = Human('Alex', 30); console.log(man); //{name: 'Alex', age: 30, getBirthYear: f}
  • 19. Паттерн Конструктор function Human(name, age) { this.name = name; this.age = age; this.getBirthYear = function () { return (new Date).getFullYear() - this.age; } } const man = new Human('Alex', 30); console.log(man); //{name: 'Alex', age: 30, getBirthYear: f}
  • 20. Паттерн Прототип function Human(name, age) { this.name = name; this.age = age; } Human.prototype.getBirthYear = function() { return (new Date).getFullYear() - this.age; } const man = new Human('Alex', 30); console.log(man); //{name: 'Alex', age: 30} console.log(man.getBirthYear()); // 2000
  • 21. Сравнение паттернов • Паттерн Фабрика – самый простой паттерн. Но он не позволяет реализовать наследование, не позволяет узнать, к какому классу относится созданный объект. • Паттерн Конструктор позволяет реализовать наследование и узнать порождающий класс. Однако в нём создаются дубликаты методов. • Паттерн Прототип расширяет конструктор, позволяя вынести общие для всех экземпляров класса методы и свойства в одну точку без дублирования.
  • 22. Порождающий конструктор • У объекта, созданного при помощи конструктора, существует свойство constructor, которое ссылается на функцию-конструктор, с помощью которой был создан объект. • Оператор instanceof принимает в себя объект и функцию и возвращает true, если объект был создан при помощи этой функции-конструктора. const man = new Human('Alex', 30); console.log(man.constructor); // Human console.log(man instanceof Human); // true
  • 23. Задача 3. • Создать класс Студент. У студента есть имя, курс, массив оценок за курс. У студента есть метод получения его среднего балла. • Создать класс Факультет. У факультета есть название и массив обучающихся студентов. Создать метод зачисления студента на факультет. Создать метод, который вернет средний балл всех студентов на факультете. • Создать 4 объекта класса Студент и один факультет. Зачислить студентов на факультет, вывести средний балл всех студентов в факультете.
  • 24. Собственные свойства • Собственными для объекта называются свойства, созданные напрямую в конструкторе либо добавленные в этот объект вручную. • Несобственными будут свойства, доступные в этом объекте, но находящиеся в прототипе. function X() { this.a = 10; this.b = 20; } X.prototype.c = 30; X.prototype.d = 40; const x = new X(); console.log(x.a, x.b, x.c, x.d);
  • 25. Установка наличия свойства • Оператор in вернет true если свойство в принципе доступно в объекте – не важно, собственное или нет. • Метод hasOwnProperty у любого объекта вернет true только если переданное в него свойство является собственным. function X() { this.a = 10; this.b = 20; } X.prototype.c = 30; X.prototype.d = 40; const x = new X(); console.log(x.a, x.b, x.c, x.d); console.log('a' in x); // true console.log('d' in x); // true console.log(x.hasOwnProperty('b')) // true console.log(x.hasOwnProperty('c')) // false
  • 26. Переопределение прототипа • Свойство constructor, присутствующее у объектов, является несобственным (прототипным). • Если в коде Вы перезаписываете прототип полностью (а не дописываете), то необходимо дополнить прототип свойством constructor вручную (см. пример) function X() { this.a = 10; } X.prototype = { constructor: X, getA() {}, getB() {}, getC() {} }
  • 27. Расширение базового прототипа • Иногда можно встретить подход, расширяющий возможности встроенных объектов, например: • Этот подход наделяет базовые объекты новыми возможностями. • Однако использовать такой подход сегодня не принято – он существенно ухудшает читаемость кода и ослабляет устойчивость кода. const arr = [10, 20, 30]; Array.prototype.sum = function() { return this.reduce((s, v) => s + v, 0); } console.log(arr.sum()); // 60
  • 28. Прототипное наследование function Car(model) { this.model = model; } Car.prototype.drive = function () { console.log('Dr-dr-dr-dr-dr'); } function AmbulanceCar(model, capacity) { Car.apply(this, [model]); // or Car.call(this, model); this.capacity = capacity; } AmbulanceCar.prototype = Object.create(Car.prototype); AmbulanceCar.prototype.alert = function () { console.log('Whe-o-whe-o-whe-o'); } const car = new Car('Volvo'); car.drive(); const ambulance = new AmbulanceCar('Volvo', 4); ambulance.drive(); ambulance.alert();
  • 29. Статические методы • Статическими методами называются методы, которые относятся ко всему классу целиком, а не только к экземпляру. function Car(model) { this.model = model; Car.amount ++; } Car.amount = 0; Car.printAmount = function() { console.log(this.amount); } const cars = [new Car('BMV'), new Car('Volvo'), new Car('Porshe')]; Car.printAmount();
  • 30. Классы в ES6 class Car { model = ''; static amount = 0; constructor(model) { this.model = model; Car.amount++; } drive() { console.log('Dr-r-r-r-r-r') } static printAmount() { console.log(this.amount); } }
  • 31. Наследование ES6 class AmbulanceCar extends Car { constructor(model, capacity) { super(model); this.capacity = capacity; } alert() { console.log('Whe-o-whe-o'); } }
  • 32. Дополнительные материалы Object.seal https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Gl obal_Objects/Object/seal Создание свойств с дескрипторами https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Gl obal_Objects/Object/defineProperty Proxy - простые примеры https://habr.com/ru/company/ruvds/blog/359060/ Proxy - описание на MDN https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Gl obal_Objects/Proxy Proxy - описание на learn.javascript.ru https://learn.javascript.ru/proxy Прототипы https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E% D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_proto types Введение в ООП https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E% D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object- oriented_JS Прототипное наследование https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E% D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Inheritance ООП в ES6 https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Cl asses