course js day 2
TRANSCRIPT
JavaScript
Georgy Grigoryev, Auriga, Inc.
2
1 вебинар
История jsСтандарт ECMAScriptIDE и редакторыЗапуск и отладка скриптовТипы и операторы
3
2 вебинар
МассивыОсновные конструкции языка, и их применениеОбъекты и JSONРегулярные выраженияКонтекст, this, bind, call, applyООП, прототипы, ООП в ECMAScript 6
4
Массивы
var array = [];console.log(typeof (array)); //выведет object
Массив – это объектМассив – имеет доступ к значениям по числовому индексу
Для определения массива – можно использовать утиную типизацию или instanceof
5
instanceof
instanceof позволяет определить является ли объект результатом создания через определенный метод
Будет работать неправильно при использовании frame для встроенных типов
function Server(name) { this.name = name; this.events = []; }var server = new Server("domain");var json_server = { "name": "mailserver", "events": [] };if (server instanceof Server) { console.log("It's server"); if (server.events instanceof Array) { console.log("server.events is array"); }} if (!(json_server instanceof Server)) { console.log("json doesn't work with instanceof"); }
6
Утиная типизация
var array = [];console.log(typeof (array));if (array.pop && array.push) { console.log("it's array");}
Если что-то плавает как утка, крякает как утка и выглядит как утка, то это утка
7
Перебор массива
Перебор массива возможен используя for с двумя разными индексамиvar array = ['c', 'c++', 'java', 'c#', 'php'];
array[6] = "javascript";
for (var i = 0; i < array.length; i++) { console.log("array[" + i + "] = " + array[i]);}
for (var i in array) { console.log("array[" + i + "] = " + array[i]);}
8
Длина массива
Свойство массива length не отображает количество элементов в массиве, а отображает последний цифровой индекс+1
Обращение к несуществующему значению в массиве по индексу вернет undefined
var array = ['c', 'c++', 'java', 'c#', 'php'];
array[9] = "javascript";console.log(array.length);for (var i = 0; i < array.length; i++) { console.log("array[" + i + "] = " + array[i]);}
9
Реализация стека: push и pop
var array = ['c', 'c++', 'java', 'c#', 'php'];
if (array.pop && array.push) {
array.push("python", "javascript");
console.log(array);
while (array.length > 0) { console.log(array.pop()); }}
Для добавления и удаления элементов в начале массива - методы shift и unshift, но они работают медленнее чем push и pop. Но для реализации очереди все равно придется их использовать.
10
try .. catch .. finally
var array = ['c', 'c++', 'java', 'c#', 'php'];try { for (var i = 0; i <= array.length; i++) { if (array[i].length > 2) { numbers.push(array[i]); } };}catch (error) { console.log(error);}finally { console.log("end of array");}
11
Методы
Методы объявляются ключевым словом functionСсылку на метод можно присвоить переменнойМетод можно назначить свойствам объектаfunction foo(text) { console.log(text);}var alert_text = function (text) { alert(text);};var method = foo;method("some text");
alert_text("new text");
window.my_method = alert_text;
window.my_method("alert from window");
12
Объявление метода
Три типа объявления методов При объявлении метода с использованием Function Declaration она будет доступна
всегда Function Declaration аналогичен объявлению через конструктор функции
Function([args],[function text]) При объявлении метода с использованием Function Expression она будет доступна
только в момент выполненияfoo("some text");alert_text("new text"); // выведет ошибку, что undefined это не функция//Function declarationfunction foo(text) { console.log(text);}//Function expressionvar alert_text = function (text) { alert(text);};
13
Декларация методов и переменных
Function declaration отрабатывает _до_ запуска кода.Такое же поведение используется для var.Специальное явление: hoisting
console.log(text);console.log(date); // выдаст ошибку ReferenceError: date is not definedvar text = "some value";console.log(text);
14
Методы и область видимости
Область видимости создается только для методовНа уровне интерпретатора она реализована через специальный объект LexicalEnvironmentvar outer_variable = true;
function check_variable() { var inner_variable = false; console.log(outer_variable); console.log(inner_variable);}
check_variable();
console.log(outer_variable);console.log(inner_variable); // выдаст ошибку ReferenceError: inner_variable is not defined
15
Замыкания
JS поддерживает замыкания Работа замыканий организована через [[Scope]] Объект не будет удален, пока на него есть ссылка хоть в одном [[Scope]]
function create_console_out() { var text = "[DEBUG] "; return function log(text_to_console) { console.log(text + text_to_console); }}
var con = create_console_out();con("error")
16
Перегрузка
Перегрузки в js не существуетКоличество аргументов у метода не строгое значениеfunction error_log(error) { console.log("[ERROR] " + error);}function error_log(error, type) { console.log("[ERROR type of " + type + "] " + error);}
var array = ['c', 'c++', 'java', 'c#', 'php'];try { for (var i = 0; i <= array.length; i++) { if (array[i].length > 2) { numbers.push(array[i]); } };}catch (error) { error_log(error); }finally { console.log("end of array") }
17
Arguments
Может содержать любые данныеНе является массивомfunction log_args(arg) { console.log(arguments); for (var key in arguments) { console.log("arguments[" + key + "] = " + arguments[key]); } var isArray = !!(arguments.push & arguments.pop); console.log("isArray is " + isArray);}
log_args("first", "second", null, true, { "name": "John Doe", "age": 32 });
18
Объекты
Объекты – составной тип Объекты состоят из свойств и перечислений При присваивании копируется ссылка Объект можно создать с помощью {}, new Object(), или function.var a = new Object(); // эквивалентно var a = {};a[name] = "John Doe";var b = a;a.name = "Bill Gates";console.log(b.name);
19
Копирование объектов
Получение всех ключей объекта производится с помощью конструкции for..in
var worker1 = {};worker1.name = "John Doe";worker1.isWorker = true;worker1.age = 32;var worker2 = {};for (var key in worker1) { worker2[key] = worker1[key];}worker1.name = "Bill Gates";console.log(worker1);console.log(worker2);
20
Произвольные поля у массива
Массиву как и любому другому объекту, можно присвоить значение свойства.
var array = ['c', 'c++', 'java', 'c#', 'php'];console.log(array);array.foo = "text";console.log(array);for (var val in array) { console.log(val);}
21
JSON
JavaScript Object NotationОбъект обозначается {}Перечисление обозначается []Поле объекта присваивается через :Название поля обрамляется кавычками “ или ‘
22
JSON
var worker = { "name": "John Doe", "age": 32, "roles": [ "admin", "user" ], "devices": [ { "type": "pc", "number": "91d40e95-021e-236f-36a6-c8c753a31dbe" }, { "type": "phone", "number": "0e50a49b-5fb8-7a9d-1b2d-e93d52b065b8" } ]};
23
Регулярные выражения
Имеют специальный синтаксис для объявления
var regex = /\w+\b/g;var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";var array = text.match(regex);console.log(array);
24
Методы работы с регулярными выражениями
RegExp.exec("string") – самый функциональный метод RegExp.test("string") – успешность поиска String.match(/regexp/) – все совпадения паттерна String.search(/regexp/) – стартовая позиция совпавшего значения String.replace(/regexp/, /regexp/) – замена по регулярному выражению String.split(/regexp/) – разделение на массив по регулярному выражению
25
RegExp.exec
Объект регулярных выражение можно использовать для перебора совпадений
Содержит позицию начала совпавшего значенияvar regexp = /\w+\b/g;
var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";var word;while (word = regexp.exec(text)) { console.log("processing word:" + word + " match index = " + word.index);
}
26
Контекст
this – это контекст выполнения метода this не фиксируется в момент создания метода, а вычисляется в момент его выполнения
this для обычного вызова метода является вызывающий объект
this можно управлять методами bind, call, apply
27
this – обычный вызов
Устаревшее поведение для методов является подставлять в this объект window
function test_this() { console.log(this);}test_this();
28
this use strict
При использовании строгого режима работы скриптов, в объект this при обычном вызове метода передается undefined
function test_this() { "use strict"; console.log(this);}test_this();
29
use strict
Специальный режим для работы скриптов используя новые версии стандарта js
Создан для использования несовместимых с предыдущими версиями стандарта
Работает в последних версиях популярных браузеров
30
Присвоение переменной
В новом стандарте создание переменной без ключевого слова var считается ошибкой
function assign_text() { new_text = "bananananana"; console.log(new_text);}
assign_text(); //bananananana
function assign_text_strict() { "use strict"; text = "bananananana"; console.log(text);}
assign_text_strict(); //ReferenceError: text is not defined
31
this как метод объекта
this присваивается объект, который вызвал метод
function do_work() { for (var hour = 9; hour < this.clock_work_till; hour++) { console.log(this.name + " does some stuff. Now is " +hour +" o'clock."); }}var worker = { "name": "John Doe", "age": 32 , "clock_work_till":17};worker.work = do_work;worker.work();
32
This для создания объектов
Объект, в классическом понимании, в js не имеет конструктора. Его можно заменить new function
function do_work() { for (var hour = 9; hour < this.clock_work_till; hour++) { console.log(this.name + " does some stuff. Now is " + hour + " o'clock."); }}
function Worker(name, age, clock_work_till, work) { this.name = name; this.age = age; this.clock_work_till = clock_work_till; this.work = work;}
var worker = new Worker("John Doe", 32, 17, do_work);worker.work();
33
bind
Метод bind служит для привязывания контекста к определенному методу для каррирования методов
Метод bind не поддерживается в <IE9function do_work() { for (var hour = 9; hour < this.clock_work_till; hour++) { console.log(this.name + " do some stuff. Now is " + hour + " o'clock."); }}
function Worker(name, age, clock_work_till, work) { this.name = name; this.age = age; this.clock_work_till = clock_work_till; this.work = work;}
var worker = new Worker("John Doe", 32, 17, do_work);var john_work = worker.work.bind(worker);
john_work();
34
Карринг методов
Карринг (каррирование) - это использование метода с заранее известными параметрами.
function Worker(name, age, clock_work_till, work) { this.name = name; this.age = age; this.work = work.bind(this, clock_work_till);}
var worker1 = new Worker("John Doe", 32, 17, do_work);var worker2 = new Worker("Bill Gates", 55, 13, do_work);
worker1.work(); //установив значение, мы можем не указывать его при вызовеworker2.work();
35
call, apply
Методы call и apply используются для явного указания контекста выполнения.
function process(obj) { var type = obj.type; switch(type){ case 1: console.log(obj.messages[0]); break; default: break; }}function log_error_message() { console.log("error, when trying to process message with type " + this.type);}var server_answer=[];server_answer.push({ "type": 1, "messages": ["John", "Bill", "Zuck"] });server_answer.push({ "type": 0, "messages": null });server_answer.push({ "type": 1, "messages": null });
for (var key in server_answer) { try { process(server_answer[key]); } catch (e) { log_error_message.call(server_answer[key]); }}
36
call, apply
Метод call от метода apply отличается лишь тем, что в метод apply можно передать массив аргументов, в то время как для метода apply вы каждый раз будете указывать их явно.
function print_arguments() { for (var key in arguments) { console.log(arguments[key]); }}
print_arguments.call(null, "first", "second", 32, true);
var args = [];args.push("c");args.push("c++");args.push("java");args.push("c#");print_arguments.apply(null, args);
37
ООП
Классы представляют собой "конструктор" и прототип. Сначала значение ищется в объекте, затем в его прототипе. Все новые значения полей объекта записываются в объект. Объекты в прототипе хранятся по ссылке, и соответственно работа с ними тоже изначально ведется по ссылке
38
Наследование
function Server(name) { this.name = name; this.events = [];}
Server.prototype.ReceiveMessage = function(message) { this.events.push(message);};Server.prototype.PrintMessages = function () { for (var key in this.events) console.log(this.events[key]);};
Server.js, MailServer.js, DomainServer.js
var servers = [];var domain = new Domain("domain", "auriga");servers.push(domain);var mailserver = new MailServer("exchange");servers.push(mailserver);
domain.events.push("restart");mailserver.events.push("sending mails");domain.events.push("authorization");
for (var key in servers) { servers[key].PrintMessages();}
AdminPage.js
function MailServer(name) { this.name = name; this.events = [];}MailServer.prototype = Object.create(Server.prototype);
function Domain(name, domain_name) { this.name = name; this.domain_name = domain_name; this.events = [];}Domain.prototype = Object.create(Server.prototype);
39
ООП в ECMAScript 6
class Server{ constructor(name) { this.name = name; }}
class MailServer extends Server{ constructor(name) { super.constructor(name); }}
class Domain extends Server{ constructor(name,domain_name) { super.constructor(name); this.domain_name = domain_name; }}
var domain = new Domain("domain", "auriga");if (domain instanceof Domain) { console.log("Domain created");}
Ключевые слова: class super extends instanceof
40
Contacts
Thank You andWe Look Forward to Working with You
Auriga, USA 92 Potter Rd, Ste 1Wilton, NH 03086, USAPhone: +1 (866) 645-1119Fax: +1 (603) [email protected] www.auriga.com
Auriga, Russia125 Varshavskoe Shosse, Unit 16A
Moscow, 117587Tel:+7 (495) 713-9900 Fax:+7 (495) 939-0300
[email protected] www.auriga.com