84
Темы лекции: ООП в JavaScript. Тренер: Игорь Шкулипа, к.т.н. JavaScript. Базовый курс Занятие 4

JavaScript Базовый. Занятие 04

Embed Size (px)

Citation preview

Page 1: JavaScript Базовый. Занятие 04

Темы лекции: ООП в JavaScript.

Тренер: Игорь Шкулипа, к.т.н.

JavaScript. Базовый курс

Занятие 4

Page 2: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 2

ООП – это парадигма программирования, основанная напредставлении предметной области в виде взаимосвязанных абстрактныхобъектов и их реализаций.

В ООП вводится понятие Класса – пользовательского типаданных, объединяющего данные и методы их обработки.

Объектом называется экземпляр класса.

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

Page 3: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 3

Члены-данные (поля) (data members) хранят всю необходимуюинформацию об объекте, формируют его состояние, характеристики ит.п.

Изменение состояния объекта или его характеристик связано сизменением данных, которые в нем содержатся.

Метод объекта (methods) – программный код, выполненный ввиде функции, реагирующий на передачу объекту определенногосообщения.

Вызов метода объекта может приводить к изменению егосостояния (значение членов-данных), а может и не приводить

Класс может содержать один или более методов, позволяющихосуществлять манипуляцию данными объекта

Поля и методы класса

Page 4: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 4

Свойство – составляющая часть объекта, доступ к которойосуществляется как к члену объекта, но таковым не является (реализуютпринцип инкапсуляции для членов объекта).

В некоторых объектно-ориентированных языкахпрограммирования (например, в C++) свойства, как элемент языка,отсутствуют.

В этом случае в класс добавляют методы, посредством которыхосуществляется доступ к необходимым переменным класса.

Свойства

Page 5: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 5

• Абстракция данных• Инкапсуляция• Наследование• Полиморфизм

Принципы ООП

Page 6: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 6

Объекты представляют неполную информацию о реальныхсущностях предметной области.

Абстракция позволяет оперировать с объектном на уровне,адекватном решаемой задаче.

Высокоуровневые обращения к объекту могут обрабатываться спомощью вызова функций и методов низкого уровня.

В основе реализации этого принципа лежит использованиеабстрактных классов интерфейсов.

Абстракция данных

Page 7: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 7

Инкапсуляция – объединение в одной оболочке данных иметодов их обработки, а так же способность объекта скрывать внутреннееустройство своих полей и методов.

Согласно данному принципу, класс должен рассматриваться какчерный ящик.

Внешний пользователь не знает детали реализации объекта иработает с ним только путем предоставленного объектом интерфейса (илиоткрытых методов доступа).

Следование данному принципу может уменьшить число связеймежду классами и упростить их независимую реализацию, модификацию итестирование.

Инкапсуляция

Page 8: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 8

Наследование позволяет описать новый класс на основе ужесуществующего родительского (базового) класса.

Класс-потомок может добавить свои собственные свойства иметоды, а так же пользоваться методами и свойствами базового класса.

Наследование позволяет строить иерархии классов.

Наследование

Page 9: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 9

Полиморфизмом называют явление, при котором классы-потомки могут изменять реализацию метода класса-предка, сохраняя егоинтерфейс.

Полиморфизм позволяет обрабатывать объекты классов-потомковкак однотипные объекты, не смотря на то, что реализация методов у нихможет различаться.

Полиморфизм

Page 10: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 10

Доступ к данным и методам класса извне может быть ограничен

Рекомендуется запрещать доступ к данным класса в обход егометодов

Для разделения прав доступа к полям класса используютсямодификаторы доступа

public

private

protected

Доступ к данным и методам класса

Page 11: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 11

public-методы и данные класса определяют его интерфейс доступк ним возможен из любой части кода.

Необходимо помещать в public-раздел класса тольконеобходимый набор методов, выполняющих высокоуровневые операциинад объектом класса

Открытые (public) поля и методы класса

Page 12: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 12

private-данные и методы класса определяют его реализацию

Доступ к ним разрешен только из методов данного класса

Рекомендуется все данные класса делать закрытыми, ихобработку осуществлять внутри методов.

Закрытые методы класса обычно используются публичнымиметодами, решая внутренние задачи класса.

Закрытые (private) поля и методы класса

Page 13: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 13

protected-данные и методы определяют интерфейс дляпроизводных классов.

Доступ к ним разрешен внутри методов данного класса и всех егопотомков.

В защищенной зоне размещают методы, которые не должны бытьвидны снаружи класса, но реализация которых может бытьпереопределена или использована производными классами.

Защищенные (protected) поля и методы класса

Page 14: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 14

Класс – тип данных.Объект – переменная этого типа.

Для инициализации состояния объекта в момент его созданиясуществует специальный метод – конструктор. Конструктор имеет то жеимя, что и имя класса.

Конструктор вызывается в момент создания экземпляра класса(объявление переменной класса или вызов оператора new).

Некоторые определения

Page 15: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 15

• Нет классов, но можно их эмулировать.• Есть наследование на прототипах - делегирующее прототипное

наследование• Все можно менять во время работы

• Цепочку наследования можно менять• Прототипы можно менять• В классах так сделать нельзя• Можно изменить прототипы базовых "классов“

• Любой объект имеет ссылку на прототип• Делегирование

• Мы можем пользоваться функциями прототипа не имеясобственных

• Цепочка прототипов• Каждый прототип - это тот же объект• Который также может иметь прототип• У прототипа прототипа также может быть прототип

Особенности ООП в JavaScript

Page 16: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 16

Объекты JavaScript представляют собой наборы свойств иметодов. Можно сказать, что свойства объектов - это данные,связанные с объектом, а методы - функции для обработки данныхобъекта.

В общем случае, объект – это неупорядоченная коллекция парключ-значение.

var o = {

firstName : ”Василий”,

lastName : ”Пупкин”,

age : 30,

};

Object

Page 17: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 17

Пустой объект:var o = new Object(); // то же, что и {}

Пустой массив:var a = new Array(); // то же, что и []

Дата/время:var d = new Date(); // текущее время

Создание объектов с помощью new

Page 18: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 18

var o = {

name:"Ivan",

surname:"Ivanov"

};

alert(o.name);

o.surname = "Petrov";

alert(o.surname);

Доступ к свойствам

Page 19: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 19

var o = {

name:"Ivan",

surname:"Ivanov"

};

alert(o["name"]);

o["surname"] = "Petrov";

alert(o["surname"]);

Объекты как ассоциативные массивы

Page 20: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 20

var o = {

name:"Ivan",

surname:"Ivanov"

};

for (var prop in o){

alert(prop);

alert(o[prop]);

}

Объекты как ассоциативные массивы

Page 21: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 21

var o = {

name:"Ivan",

surname:"Ivanov"

};

o.middle = "Ivanovich";

o.gender = "Male";

for (var prop in o){

alert(o[prop]);

}

Добавление свойств

Page 22: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 22

var o = {

name:"Ivan",

surname:"Ivanov"

};

o.middle = "Ivanovich";

o.gender = "Male";

delete o.gender;

delete o["middle"];

delete o["someprop1"];

delete o.someprop2;

for (var prop in o){

alert(o[prop]);

}

Удаление свойств

Page 23: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 23

this возвращает ссылку на объект, являющийся текущимконтекстом вызова. Это позволяет обращаться к свойствам "текущего"объекта: this.property.

Текущий объект не является жестко фиксированным и зависит отконтекста вызова функции. Он является, своего рода, скрытымпараметром.

this

Page 24: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 24

var o = {

name:"Ivan",

surname:"Ivanov"

};

o.middle = "Ivanovich";

o.gender = "Male";

o.alertme1 = function() {

alert(this.name);

}

o.alertme2 = alerto;

o.alertme1();

o.alertme2();

function alerto() {

alert(this.name);

}

Методы

Page 25: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 25

Объекты в JavaScript можно организовать в цепочки так, чтобысвойство, не найденное в одном объекте, автоматически искалось бы вдругом.

Связующим звеном выступает специальное свойство __proto__.

Объект, на который указывает ссылка __proto__, называется«прототипом».

Прототип объекта

Page 26: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 26

var o = {

name:"Ivan",

surname:"Ivanov"

};

var oproto = {

gender:"Male"

};

o.__proto__ = oproto;

for (var prop in o){

alert(o[prop]);

}

__proto__

Page 27: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 27

var oproto = {

gender:"Male"

};

var o = Object.create (oproto, {

name:{

value:"Ivan",

writable:true,

configurable:true,

enumerable:true

},

surname:{

value:"Ivanov",

writable:true,

configurable:true,

enumerable:true

}

})

for (var prop in o){

alert(o[prop]);

}

Object.create()

Page 28: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 28

Object.create(prototype, descriptors)

Дескрипторы свойств, присутствующие в объектах, бывают двух основныхтипов: дескрипторы данных и дескрипторы доступа.

Дескриптор данных — это свойство, имеющее значение, которое может быть (аможет и не быть) записываемым.

Дескриптор доступа — это свойство, описываемое парой функций — геттероми сеттером. Дескриптор может быть только чем-то одним из этих двух типов; он неможет быть одновременно обоими.

И дескриптор данных, и дескриптор доступа являются объектами. Ониобладают следующими обязательными ключами:

• configurable - равен true только в том случае, если тип этого дескрипторасвойства может быть изменён и если свойство может быть удалено изсодержащего его объекта. Значение по умолчанию установлено в false.

• enumerable - равен true только в том случае, если это свойство можно увидетьчерез перечисление свойств содержащего его объекта. Значение поумолчанию установлено в false.

Object.create()

Page 29: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 29

Дескриптор данных также может содержать следующие дополнительные ключи:

• value - значение, ассоциированное со свойством. Может быть любымдопустимым значением JavaScript (числом, объектом, функцией и т.д.).Значение по умолчанию установлено в undefined.

• writable - равен true только в том случае, если значение, ассоциированноесо свойством, может быть изменено с помощью оператора присваивания.Значение по умолчанию установлено в false.

Дескриптор доступа также может содержать следующие дополнительные ключи:

• get - функция, используемая как геттер свойства, либо undefined, еслисвойство не имеет геттера. Возвращаемое значение функции будетиспользоваться как значение свойства. Значение по умолчанию установленов undefined.

• set - функция, используемая как сеттер свойства, либо undefined, еслисвойство не имеет сеттера. Функция принимает единственным аргументомновое значение, присваиваемое свойству. Значение по умолчаниюустановлено в undefined.

Object.create()

Page 30: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 30

var oproto = {

gender:"Male"

};

var o = Object.create (oproto, {

name:{

value:"Ivan",

writable:true,

configurable:true,

enumerable:true

},

surname:{

value:"Ivanov",

writable:true,

configurable:true,

enumerable:true

}

})

oproto.gender="Not Set";

for (var prop in o){

alert(o[prop]);

}

Прототип

Page 31: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 31

...

Object.defineProperty(o,

"middle", {

enumerable: true,

configurable: true,

writable: true,

value: "Ivanovich"

});

for (var prop in o){

alert(o[prop]);

}

Object.defineProperty

Page 32: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 32

...

for (var prop in o){

if (o.hasOwnProperty(prop))

alert(o[prop]);

}

obj.hasOwnProperty(prop)

Page 33: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 33

Все объекты базовый набор методов, например метод toString,которые находится, не в самом объекте, а в его прототипе obj.__proto__.

Объект Object.prototype — вершина иерархии, единственный, укоторого __proto__ равно null.

Поэтому говорят, что «все объекты наследуют от Object», а еслиболее точно, то от Object.prototype.

Object.prototype

Page 34: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 34

Любая функция, кроме некоторых встроенных, может создать объект.

Для этого ее нужно вызвать через директиву new.

Такие функции еще называются конструкторами.

function FullName (name, surname, middle) {

this.name = name;

this.surname = surname;

this.middle = middle;

return this; // не обязательно

}

var fullName= new FullName (“Ivan“, “Ivanov”, “Ivanovich”);

Создание объектов с помощью функций

Page 35: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 35

function FullName (name, surname, middle) {

this.name = name;

this.surname = surname;

this.middle = middle;

this.alertme = function (){

alert(this.name);

}

return this; // не обязательно

}

var o1= new

FullName("Ivan", "Ivanov", "Ivanovich");

var o2= new

FullName("Petr", "Petrov", "Petrovich");

o1.alertme();

o2.alertme();

Конструкторы

Page 36: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 36

function FullName (name, surname, middle) {

this.name = name;

this.surname = surname;

this.middle = middle;

this.alertme = function (){

alert(this.name);

}

return {

name: "Sidor",

surname: "Sidorov",

middle: "Sidorovich",

alertme: function () {

alert(this.name);

}

};

}

var o1= new

FullName("Ivan", "Ivanov", "Ivanovich");

var o2= new

FullName("Petr", "Petrov", "Petrovich");

o1.alertme();

o2.alertme();

Конструкторы

Page 37: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 37

Чтобы новым объектам автоматически ставить прототип,конструктору ставится свойство prototype.

При создании объекта через new, в его прототип __proto__записывается ссылка из prototype функции-конструктора.

Как правило, свойство prototype используется дляпредоставления базового набора функциональных возможностей классуобъектов. Новые экземпляры объекта "наследуют" поведение прототипа,присвоенного этому объекту.

F.prototype

Page 38: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 38

var nameObj = { name: "", gender:""};

function Initials(name, middle){

this.name = name;

this.middle = middle;

}

function SurnName(name, surname){

this.name = name;

this.surname = surname;

}

Initials.prototype = nameObj;

SurnName.prototype = nameObj;

Initials.prototype.alertme = function () {

alert(this.name + " " +

this.surname + " " + this.gender);

}

var initials = new

Initials("Ivan", "Ivanovich");

var surnname = new

SurnName("Petr", "Petrov");

nameObj.gender = "male";

initials.alertme();

surnname.alertme();

nameObj.alertme();

Пример

Page 39: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 39

Результат

Page 40: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 40

В prototype по умолчанию всегда находится свойствоconstructor, указывающее на функцию-конструктор. Но, если мырассчитываем использовать это свойство, то при замене prototype черезObject.create нужно его явно сохранить.

obj.prototype = Object.create(null);

obj.prototype.constructor = Object;

JavaScript никак не использует свойство constructor. То есть,оно создаётся автоматически, а что с ним происходит дальше — это уженаша забота. В стандарте прописано только его создание.

В частности, при перезаписи obj.prototype = { } свойстваconstructor больше не будет.

Свойство constructor

Page 41: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 41

var nameObj = { name: "", gender:""};

function Initials(name, middle){

this.name = name;

this.middle = middle;

}

function SurnName(name, surname){

this.name = name;

this.surname = surname;

}

SurnName.prototype = nameObj;

Initials.prototype.alertme = function () {

alert(this.name + " " + this.surname + " " +

this.gender);

}

var initials = new Initials("Ivan", "Ivanovich");

var surnname = new SurnName("Petr", "Petrov");

nameObj.gender = "male";

Пример

Page 42: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 42

alert(surnname.constructor); // ???

alert(surnname.__proto__.constructor); // ???

alert(initials.constructor); // ???

alert(initials.__proto__.constructor); // ???

alert(surnname.hasOwnProperty("name")); // ???

alert(surnname.hasOwnProperty("surname")); // ???

alert(surnname.hasOwnProperty("toString")); // ???

alert(Object.prototype.isPrototypeOf(surnname)); // ???

Пример

Page 43: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 43

alert(surnname.constructor);

alert(surnname.__proto__.constructor);

alert(initials.constructor);

alert(initials.__proto__.constructor);

alert(surnname.hasOwnProperty("name"));

alert(surnname.hasOwnProperty("surname"));

alert(surnname.hasOwnProperty("toString"));

alert(Object.prototype.isPrototypeOf(surnname));

Пример

Page 44: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 44

Все, что добавляется в this является public

function FullName (name, surname, middle) {

this.name = name;

this.surname = surname;

this.middle = middle;

this.alertme = function (){

alert(this.name);

}

return this;

}

var o1= new

FullName("Ivan", "Ivanov", "Ivanovich");

var o2= new

FullName("Petr", "Petrov", "Petrovich");

o1.alertme();

o2.alertme();

public

Page 45: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 45

Все, что объявляется внутри конструктора, включая его параметры, является private

function FullName (name, surname, middle) {

var fullName=name + " " + middle + " " + surname;

this.name = name;

this.surname = surname;

this.middle = middle;

this.alertme = function (){

alert(fullName);

}

return this;

}

var o1= new

FullName("Ivan", "Ivanov", "Ivanovich");

var o2= new

FullName("Petr", "Petrov", "Petrovich");

o1.alertme();

o2.alertme();

private

Page 46: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 46

protected - это, по сути, public, отмеченный «_» в началеидентификатора. И мы «договариваемся» эти свойства не трогать.

function FullName (name, surname, middle) {

var fullName=name + " " + middle + " " + surname;

this.name = name;

this.surname = surname;

this.middle = middle;

this._fullName = fullName;

this.alertme = function (){

alert(this._fullName);

}

return this;

}

var o1= new

FullName("Ivan", "Ivanov", "Ivanovich");

var o2= Object.create(new

FullName("Petr", "Petrov", "Petrovich"));

o1.alertme();

alert(o2._fullName);

protected

Page 47: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 47

function Name () {

var name;

this.getName = function () {

return name;

}

this.setName = function (nm) {

nm = nm || null;

if (nm && (nm.length > 0))

name=nm;

else name="";

}

}

var n1=new Name();

var n2=new Name();

var n3=new Name();

n1.setName();

n2.setName(2);

n3.setName("3");

alert(n1.getName());

alert(n2.getName());

alert(n3.getName());

Инкапсуляция

Page 48: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 48

var n0 = Object.create(null,{

name:{

configurable: true,

enumerable: true,

get: function () {

return name + ", hello GET!";

},

set: function (nm) {

nm = nm || null;

if (nm && (nm.length > 0))

name=nm;

else name="Default";

}

}

});

n0.name="Ivan";

alert(n0.name);

n0.name="";

alert(n0.name);

Инкапсуляция 2

Page 49: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 49

function Name () {

var name;

this.getName = function () {

return name;

}

this.setName = function (nm) {

nm = nm || null;

if (nm && (nm.length > 0))

name=nm;

else name="";

}

}

function FullName () {

Name.call(this);

var surname = "S";

var middle = "M";

this.getName = function (){

return name + " " +

middle + " " + surname;

}

}

Наследование

Page 50: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 50

function Name () {

this._name="";

this.getName = function () {

return this._name;

}

this.setName = function (nm) {

nm = nm || null;

if (nm && (nm.length > 0))

this._name=nm;

else this._name="";

}

}

function FullName () {

Name.call(this);

var surname = "S";

var middle = "M";

this.getName = function (){

return this._name + " " +

middle + " " + surname;

} }

var n1= new FullName();

var n2= new FullName();

var n3= new FullName();

n1.setName();

n2.setName(2);

n3.setName("3");

alert(n1.getName());

alert(n2.getName());

alert(n3.getName());

Наследование

Page 51: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 51

Сериализация (в программировании) — процесс переводакакой-либо структуры данных в последовательность битов. Обратной коперации сериализации является операция десериализации(структуризации) — восстановление начального состояния структурыданных из битовой последовательности.

Почти все языки программирования имеют библиотеки дляпреобразования объектов в формат JSON.

Основные методы для работы с JSON в JavaScript — это:

• JSON.parse — читает объекты из строки в формате JSON.

• JSON.stringify — превращает объекты в строку в формате JSON,

используется, когда нужно из JavaScript передать данные по сети.

Сериализация

Page 52: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 52

JSON (JavaScript Object Notation) — текстовый формат обмена данными,основанный на JavaScript.

JSON строится на двух структурах:• Коллекция пар ключ/значение. В разных языках, эта концепция

реализована как объект, запись, структура, словарь, хэш, именованныйсписок или ассоциативный массив.

• Упорядоченный список значений. В большинстве языков это реализованокак массив, вектор, список или последовательность.

В JSON используются их следующие формы:• Объект — это неупорядоченное множество пар имя/значение,

заключённое в фигурные скобки { }. Между именем и значением стоитсимвол ": ", а пары имя/значение разделяются запятыми.

• Массив (одномерный) — это множество значений, имеющих порядковыеномера (индексы). Массив заключается в квадратные скобки [ ]. Значенияотделяются запятыми.

• Значение может быть строкой в двойных кавычках, числом, значениемtrue или false, объектом, массивом, или значением null. Эти структурымогут быть вложены друг в друга.

• Строка — это упорядоченное множество из нуля или более символовюникода, заключенное в двойные кавычки, с использованием escape-последовательностей начинающихся с обратной косой черты (backslash).Символы представляются простой строкой.

• Имя — это строка.

JSON

Page 53: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 53

Пример 1.

var fio= {surname:‘Пупкин',name:‘Василий',middle:‘Борисович'};

Пример 2. Wikipedia.

{

"firstName": "Иван",

"lastName": "Иванов",

"address": {

"streetAddress": "Московское ш., 101, кв.101",

"city": "Ленинград",

"postalCode": 101101

},

"phoneNumbers": [

"812 123-1234",

"916 123-4567"

]

}

Примеры JSON

Page 54: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 54

var initialsString= JSON.stringify(initials);

var surnnameString= JSON.stringify(surnname);

alert(initialsString);

alert(surnnameString);

var ini= JSON.parse(initialsString);

var sur= JSON.parse(surnnameString);

alert(ini.name);

alert(sur.name);

Сериализация

Page 55: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 55

Ошибки в скриптах делятся на два типа:

• Синтаксические ошибки — когда нарушена структура кода.Обычно это ошибки программиста. Их также называют «ошибкивремени компиляции», поскольку они происходят на этаперазбора кода.

• Семантические ошибки, также называемые «ошибки временивыполнения» — возникают, когда браузер смог прочитать скрипти уже выполняет код, но вдруг натыкается на проблему.

Обработка исключений

Page 56: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 56

• Выполняется код внутри блока try.• Если в нём возникнет ошибка, то выполнение try прерывается, и

управление прыгает в начало блока catch.

try {

alert("Start try");

a;

alert("End of try");

} catch (error) {

alert("Error catched!");

}

Конструкция try-catch. С ошибкой

Page 57: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 57

try {

alert("Start try");

var a;

alert("End of try");

} catch (error) {

alert("Error catched!");

}

Конструкция try-catch. Без ошибок

Page 58: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 58

У блока catch есть аргумент, в примере выше он обозначен error. Это — объект ошибки или, как ещё говорят, объект исключения (exception object).

Он содержит информацию о том, что произошло, и может бытьразным, в зависимости от ошибки.

Как правило, error — объект встроенного типа Error и производных от него.

Есть несколько свойств, которые присутствуют в объекте ошибки:

• name - тип ошибки. Например, при обращении к несуществующей переменной равен "ReferenceError".

• message - текстовое сообщение о деталях ошибки.

• stack - везде, кроме IE<9, есть также свойство stack, указывающее, где в точности произошла ошибка.

Объект ошибки

Page 59: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 59

try {

alert("Start try");

a;

alert("End of try");

} catch (error) {

alert(error);

}

Объект ошибки

Page 60: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 60

try {

alert("Start try");

var a = 1;

var b = a();

alert("End of try");

} catch (error) {

alert(error);

}

Объект ошибки

Page 61: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 61

try {

alert("Start try");

var a = 1;

var b = a();

alert("End of try");

} catch (error) {

alert(error);

} finally {

alert("Finally");

}

Блок finally позволяет избежать дублирования кода в try-catch.

Секция finally

Page 62: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 62

Блок finally срабатывает при любом выходе из try-catch, в том числе иreturn. Это гарантирует освобождение ресурсов в любом случае.

function f() {

try {

alert("Start try");

return 1;

} catch (error) {

alert(error);

} finally {

alert("Finally");

}

}

f();

finally и return

Page 63: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 63

throw <объект ошибки>

Инициирует ошибку, которую можно поймать в catch. Объектом ошибки может быть что угодно, например число.

try {

alert("Start try");

throw 1;

} catch (error) {

alert(error);

} finally {

alert("Finally");

}

Генерация ошибок

Page 64: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 64

В случае вложенных вызовов — не важно, где было исключение, оно будет поймано ближайшим внешним try-catch.

function f() {

while (true) {

throw 1;

}

}

try {

alert("Start try");

f();

} catch (error) {

alert(error);

} finally {

alert("Finally");

}

Всплывание ошибок

Page 65: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 65

try {

try {

alert("Start try");

f();

alert("End try");

} catch (error) {

if (error instanceof String)

alert(error);

else throw error;

} finally {

alert("Finally");

}

} catch (err) {

alert(err + " external try");

}

Вложенные блоки try..catch

Page 66: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 66

SOLID – это акроним названий пяти основных принциповпроектирования классов, сформулированных Робертом Мартином:

• Single responsibility (принцип одной ответственности),

• Open for extension and closed for modification (принципоткрытости/закрытости, или открытость для расширения изакрытость для модификации),

• Liskov substitution (принцип подстановки Лисков),

• Interface segregation (принцип разделения интерфейса),

• Dependency inversion (принцип инверсии зависимостей).

SOLID. Принципы проектирования

Page 67: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 67

Принцип единственной ответственности (Single ResponsibilityPrinciple) часто определяют так: у объекта должна быть только однапричина для изменения; чем больше файл или класс, тем труднеедостичь этой цели.

Этот принцип говорит о том, что по-хорошему каждый классдолжен решать только одну задачу. Это совсем не значит, что в класседолжен быть всего один метод. Это означает, что методы класса должныбыть связаны одной общей целью.

Single Responsibility

Page 68: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 68

Single Responsibility

Плохой пример Неплохой пример

function Persone(name, surname, middle) {

this.name=name;

this.surname=surname;

this.middle=middle;

return this;

}

Persone.prototype.LoadFromDatabase =

function () {}

Persone.prototype.SaveToDatabase =

function () {}

Persone.prototype.PrintToPrinter =

function () {}

function Persone(name, surname, middle) {

this.name=name;

this.surname=surname;

this.middle=middle;

return this;

}

function PersoneDatabase() {

return this;

}

PersoneDatabase.prototype.LoadFromDatabase =

function () { return new Persone(...);}

PersoneDatabase.prototype.SaveToDatabase =

function (p) { }

function PersonePrinter() {

return this;

}

PersonePrinter.prototype.PrintToPrinter =

function (p) { }

Page 69: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 69

Объекты проектирования (классы, функции, модули и т.д.)должны быть открыты для расширения, но закрыты для модификации.

Этот принцип говорит о том, что классы нужно проектироватьтак, чтобы впоследствии иметь возможность изменять поведение класса,не изменяя его код.

Open for Extension and Closed for Modification

Page 70: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 70

Open for Extension and Closed for Modification

Плохой пример Неплохой пример

function PersonePrinter () {

}

PersonePrinter.prototype.PrintToPrinter =

function (p) { }

function PersonePrinter () {

}

PersonePrinter.prototype.PrintToPrinter =

function (p) { }

PersonePrinter.prototype.PrintToPrinterShortForm =

function (p) { }

PersonePrinter.prototype.PrintToPrinterDetailedForm =

function (p) { }

function PersonePrinter () {

}

PersonePrinter.prototype.PrintToPrinter =

function (persone, printForm) { }

var PrintForm = { formats : [] }

function PrintFormGeneral () { }

PrintFormGeneral.prototype = PrintForm;

function PrintFormShort () { }

PrintFormShort.prototype = PrintForm;

function PrintFormDetailed () { }

PrintFormDetailed.prototype = PrintForm;

Page 71: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 71

Функции, которые используют ссылки на базовые классы, должныиметь возможность использовать объекты производных классов, не зная обэтом.

Liskov Substitution

Page 72: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 72

Liskov Substitution

Плохой пример Неплохой пример

function PersonePrinter () {

}

PersonePrinter.prototype.PrintToPrinter =

function (persone, printForm) {

//...

if (printForm instanceof PrintFormGeneral)

{ }

//...

if (printForm instanceof PrintFormShort)

{ }

}

function PersonePrinter () {

}

PersonePrinter.prototype.PrintToPrinter =

function (persone, printForm) {

//...

printForm.formatReport(persone);

//...

}

Page 73: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 73

Interface Segregation

Плохой пример Неплохой пример

function Employee () {

this.UseComputer = function () { };

this.Develop = function () { };

this.Test = function () { };

}

function SoftDeveloper (){

Employee.call(this);

this.Develop = function() { }

this.Test = function() {/* How ? */ }

return this;

}

function SoftTester (){

Employee.call(this);

this.Develop = function() { /* How ? */ }

this.Test = function() { }

return this;

}

function Employee () {

this.UseComputer = function () { };

}

function SoftDeveloper (){

Employee.call(this);

this.Develop = function() { }

return this;

}

function SoftTester (){

Employee.call(this);

this.Test = function() { }

return this;

}

Page 74: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 74

• Модули верхних уровней не должны зависеть от модулейнижних уровней.

• Оба типа модулей должны зависеть от абстракций.

• Абстракции не должны зависеть от реализаций.

• Реализации должны зависеть от абстракций.

Dependency Inversion

Page 75: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 75

Dependency Inversion

Плохой пример Неплохой пример

function SoftDeveloper () {

this.Develop = function () { }

}

function Manager () {

var softDeveloper = new SoftDeveloper();

this.Manage = function() {

softDeveloper.Develop();

}

}

function SoftDeveloper () {

this.Develop = function () { }

}

function Manager (softDeveloper) {

var sd = softDeveloper;

this.Manage = function() {

sd.Develop();

}

}

Page 76: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 76

Паттерн описывает задачу, которая снова и снова возникает в работе, а также принцип ее решения, причем таким образом, что это решение можно потомиспользовать много раз, ничего не изобретая заново.

В общем случае паттерн состоит из четырех основных элементов:

• Имя. Присваивание паттернам имен позволяет проектировать на более высокомуровне абстракции. С помощью имен паттернов можно вести общение с коллегами.Назначение паттернам имен упрощает общение в профессиональной среде.

• Задача - это описание того, когда следует применять паттерн. Необходимосформулировать задачу и ее контекст. Может описываться конкретная проблемапроектирования, например способ представления алгоритмов в виде объектов. Также задача может включать перечень условий, при выполнении которых имеетсмысл применять данный паттерн.

• Решение представляет собой описание элементов дизайна, отношений междуними, функций каждого элемента. Конкретный дизайн или реализация не имеютсяввиду, поскольку паттерн – это шаблон, применимый в самых разных ситуациях.

• Результаты - это следствия применения паттерна и разного рода компромиссы.Хотя при описании проектных решений о последствиях часто не упоминают, знатьо них необходимо, чтобы можно было выбрать между различными вариантами иоценить преимущества и недостатки данного паттерна.

Паттерны (шаблоны проектирования)

Page 77: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 77

Паттерны проектирования программных систем делятся наследующие категории:

• Архитектурные паттерны. Описывают структурную схемупрограммной системы в целом. В данной схеме указываются отдельныефункциональные составляющие системы, называемые подсистемами, атакже взаимоотношения между ними.

• Паттерны проектирования. описывают схемы детализациипрограммных подсистем и отношений между ними, при этом они невлияют на структуру программной системы в целом и сохраняютнезависимость от реализации языка программирования.

• Идиомы - низкоуровневые паттерны, имеют дело с вопросамиреализации какой-либо проблемы с учетом особенностей данного языкапрограммирования.

Классификация паттернов

Page 78: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 78

Паттерны проектирования делятся на следующие категории:

• Порождающие - шаблоны проектирования, которые абстрагируютпроцесс создания объектов. Они позволяют сделать систему независимойот способа создания, композиции и представления объектов.

• Структурные - шаблоны проектирования, в которых рассматриваетсявопрос о том, как из классов и объектов образуются более крупныеструктуры.

• Поведенческие - шаблоны проектирования, определяющиеалгоритмы и способы реализации взаимодействия различных объектов иклассов.

Паттерны проектирования (GoF)

Page 79: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 79

• Singleton (Одиночка) - контролирует создание единственногоэкземпляра некоторого класса и предоставляет доступ к нему.

• Factory Method (Фабричный метод) - В его классическом вариантевводится полиморфный класс Factory, в котором определяетсяинтерфейс фабричного метода, а ответственность за созданиеобъектов конкретных классов переносится на производные от Factoryклассы, в которых этот метод переопределяется.

• Abstract Factory (Абстрактная фабрика) - использует несколькофабричных методов и предназначен для создания целого семействаили группы взаимосвязанных объектов.

• Builder (Строитель) - определяет процесс поэтапного конструированиясложного объекта, в результате которого могут получаться разныепредставления этого объекта.

• Prototype (Прототип) - создает новые объекты с помощью прототипов.Прототип - некоторый объект, умеющий создавать по запросу копиюсамого себя.

• Object Pool (Пул объектов) - используется в случае, когда созданиеобъекта требует больших затрат или может быть создано толькоограниченное количество объектов некоторого класса.

Порождающие паттерны

Page 80: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 80

• Adapter представляет собой программную обертку над ужесуществующими классами и предназначен для преобразования ихинтерфейсов к виду, пригодному для последующего использования вновом программном проекте.

• Bridge отделяет абстракцию от реализации так, что то и другоеможно изменять независимо.

• Composite группирует схожие объекты в древовидные структуры.Рассматривает единообразно простые и сложные объекты.

• Decorator используется для расширения функциональности объектов.Являясь гибкой альтернативой порождению классов, паттернDecorator динамически добавляет объекту новые обязанности.

• Facade предоставляет высокоуровневый унифицированныйинтерфейс к набору интерфейсов некоторой подсистемы, чтооблегчает ее использование.

• Flyweight использует разделение для эффективной поддержкимножества объектов.

• Proxy замещает другой объект для контроля доступа к нему.

Структурные шаблоны проектирования

Page 81: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 81

• Паттерн Chain of Responsibility позволяет обработать запроснескольким объектам-получателям. Получатели связываются вцепочку, и запрос передается по цепочке, пока не будет обработанкаким-то объектом. Паттерн Chain of Responsibility позволяет такжеизбежать жесткой зависимости между отправителем запроса и егополучателями.

• Паттерн Command преобразовывает запрос на выполнение действия вотдельный объект-команду. Это придает системе гибкость: позволяетосуществлять динамическую замену команд, использовать сложныесоставные команды, осуществлять отмену операций.

• Паттерн Iterator предоставляет механизм обхода элементов составныхобъектов (коллекций) не раскрывая их внутреннего представления.

• Паттерн Interpreter предназначен для решения повторяющихсязадач, которые можно описать некоторым языком. Для этого паттернInterpreter описывает решаемую задачу в виде предложений этогоязыка, а затем интерпретирует их.

• Паттерн Mediator инкапсулирует взаимодействие совокупностиобъектов в отдельный объект-посредник. Уменьшает степеньсвязанности взаимодействующих объектов - им не нужно хранитьссылки друг на друга.

Шаблоны поведения

Page 82: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 82

• Паттерн Memento получает и сохраняет за пределами объекта еговнутреннее состояние так, чтобы позже можно было восстановить объект втаком же состоянии.

• Паттерн Observer определяет зависимость "один-ко-многим" междуобъектами так, что при изменении состояния одного объекта всезависящие от него объекты уведомляются и обновляются автоматически.

• Паттерн State позволяет объекту изменять свое поведение в зависимостиот внутреннего состояния. Создается впечатление, что объект изменилсвой класс. Паттерн State является объектно-ориентированнойреализацией конечного автомата.

• Если поведение системы настраивается согласно одному из некоторогомножества алгоритму, то применение паттерна Strategy переноситсемейство алгоритмов в отдельную иерархию классов, что позволяетзаменять один алгоритм другим в ходе выполнения программы. Крометого, такую систему проще расширять и поддерживать.

• Паттерн Template Method определяет основу алгоритма и позволяетподклассам изменить некоторые шаги этого алгоритма без изменения егообщей структуры.

• Паттерн Visitor определяет операцию, выполняемую на каждом элементеиз некоторой структуры без изменения классов этих объектов.

Шаблоны поведения

Page 83: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 83

var Singleton = (function () {

var instance;

function createInstance() {

return {

name: "Ivan",

surname: "Ivanov",

alertme: function () {

alert(this.name+" "+this.surname);}

}

}

return {

getInstance: function () {

if (!instance) {

instance = createInstance();

}

return instance;

}

};

})();

var instance1 = Singleton.getInstance();

instance1.name= "Petr";

var instance2 = Singleton.getInstance();

alert(instance1 === instance2);

instance1.alertme();

instance2.alertme();

Шаблон проектирования Singleton

Page 84: JavaScript Базовый. Занятие 04

http://www.slideshare.net/IgorShkulipa 84

Применяется, когда нужен только один экземпляр класса.Например для хранения глобальной конфигурации системы, дляведения логов, связи с базой данных и т.д.

Основное преимущество перед глобальными переменными втом, что экземпляр класса создается не при инициализациипрограммы, а по первому требованию.

Применение Singleton