SlideShare a Scribd company logo
1 of 58
О себе
Александр Кучеренко
• В DataArt 1,5 месяца
• Занимаюсь программированием 7+ лет
• За это время писал на: PHP, JavaScript,
ActionScript3, C#, Java(Android), Objective-C
Поговорим о JavaScript
1. Объекты в JavaScript, лямбды,
замыкания.
2. Deferred & Promises.
3. Библиотека Q.
С чего начиналось
С чего все начиналось:
• Ajax
• Web 2.0
• jQuery
Что сейчас
• Полноценные веб приложения (GoogleDoc, eyeOs, FirefoxOS,
ChromeOS)
• Мобильные приложения (PhoneGap, jQuery Mobile, Sencha
Touch)
• Серверный JavaScript (Node JS)
• Инструменты (MongoDB, JSON, NPM, Bower, Grunt)
• Тестирование: Buster.js, Karma, TestSwarm, JsTestDriver, YUI Yeti,
Jasmine, QUnit, Sinon
• 3D графика WebGL
Базовые типы
Элементарные
• Number
• Boolean
• String
• Null
• undefined
String
Array
Date
Объекты
Function
…
Number
• Float64 - 8 байт
• console.log(0.1+0.2)
> 0.3 ?
> 0.30000000000000004
• BCMath for JavaScript
• 0.1234.toFixed(2) = 0.12
Number
• При операциях с Number - никогда не происходят
ошибки. Зато могут быть возвращены специальные
значения
• 1/0 = Number.POSITIVE_INFINITY (плюс бесконечность)
• -1/0 = Number.NEGATIVE_INFINITY (минус бесконечность)
• Положительная бесконечность
Number.POSITIVE_INFINITY больше любого Number, и
даже больше самой себя.
Number
• NaN - особый результат
• Любая математическая операция с NaN дает NaN:
– NaN + 1 = NaN
• NaN не равен сам себе:
– NaN == NaN // false
• Можно проверить с помощью функции isNaN:
– isNaN(NaN) // true
String
• Строки в javascript - полностью юникодные
• Кавычки двойные и одинарные работают одинаково
• Можно указывать юникодные символы через
uXXXX:
• Встроены регулярные выражения, методы
replace/match:
"превед медвед".replace(/(.*?)s(.*)/, "$2, $1!") // => медвед, превед!
Boolean
• False
– false
– null
– undefined
– “”
– 0
– Number.NaN
• True – все остальное
– “0” (В PHP FALSE)
– “false”
undefined
• При попытке доступа к глобальной переменной undefined (если
она не изменена).
• Неявный возврат из функции при отсутствии в ней оператора
return.
• Из операторов return, которые ничего не возвращают.
• В результате поиска несуществующего свойства у объекта (и
доступа к нему).
• Параметры, которые не были переданы в функцию явно.
• При доступе ко всему, чьим значением является undefined.
undefined
• undefined — это тип с единственным возможным
значением: undefined
• Не являясь константой, она не является и ключевым
словом. Можно с лёгкостью переопределить
// Happy debugging suckers ...
undefined = true;
(function(something, foo, undefined) {
// в локальной области видимости `undefined`
// снова ссылается на правильное значене.
})('Hello World', 42);
NULL
• Используется во внутренних механизмах
JavaScript (например для определения
конца цепочки прототипов за счёт
присваивания Foo.prototype = null)
Объекты
• В JavaScript всё ведет себя, как объект, лишь
за двумя исключениями — NULL и
UNDEFINED.
• Почему у примитивов можно вызвать
методы?
Объекты и примитивы
var number = 2;
// Можно вызвать метод
console.log(number.toString()); // -> 2
// Попробуем задать свойство
number.newProperty = 3;
console.log(number.newProperty); // -> undefined
// Если нельзя, но сильно хочется, то - можно
Number.prototype.newProperty = 3;
console.log(number.newProperty); // -> 3
Function
• Функции в JavaScript тоже являются
объектами
Пример №1:
foo(); // сработает, т.к. функция будет создана до выполнения кода
function foo() {}
Пример №2:
foo; // 'undefined'
foo(); // вызовет TypeError
var foo = function() {};
Область видимости
Пример №1:
function test() { // область видимости
for(var i = 0; i < 10; i++) { // не область видимости
// считаем
}
console.log(i); // 10
}
Хотя JavaScript нормально понимает синтаксис двух фигурных скобок,
окружающих блок, он не поддерживает блочную область видимости; всё что
остаётся на этот случай в языке — область видимости функций.
Как работает this
1. Глобальная область видимости
Когда мы используем this в глобальной области, она будет просто ссылаться
на глобальный объект.
Различают ровно пять вариантов того, к чему привязывается this в языке.
4. Вызов конструктора
new foo();
Если перед вызовом функции присутствует ключевое слово new то данная
функция будет действовать как конструктор. Внутри такой функции this будет
указывать на новосозданный Object.
2. Вызов функции
foo(); // Тут this также ссылается на глобальный объект
3. Вызов метода
test.foo(); // Тут this также ссылается на глобальный объект.
Как работает this
5. Переопределение this
Переопределить this можно с помощью методов apply, call и bind
Пример №1:
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // массив развернётся в a = 1, b = 2, c = 3
foo.call(bar, 1, 2, 3); // аналогично
Как работает this
Пример самой распространённой ошибки:
Foo.method = function() {
function test() {
// this ???
}
test();
}
Как работает this
Пример самой распространённой ошибки:
Foo.method = function() {
function test() {
// this ссылается на глобальный объект
}
test();
}
Как работает this
Достойно выходим из ситуации:
Foo.method = function() {
var that = this;
function test() {
// Здесь используем that вместо this
}
test();
}
Как работает this
А что если…
var test = someObject.methodTest;
test();
Как работает this
А что если…
var test = someObject.methodTest;
test();
Следуя первому правилу test вызывается как обычная функция; следовательно
this внутри него больше не ссылается на someObject
Хотя позднее связывание this на первый взгляд может показаться плохой идеей,
но на самом деле именно благодаря этому работает наследование прототипов.
Замыкания
Замыкание в JavaScript:
function outerFn(myArg) {
var myVar = 42;
function innerFn() {
// имеет доступ к myVar и myArg
}
}
Замыкания
Замыкание в PHP:
function getNumber() {
$id = 42;
return function() use ($id){
return $id*2;
};
}
Замыкания
Классика:
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}
, 1000);}
Замыкания
• Каждое выполнение функции хранит все
переменные в специальном объекте с
кодовым именем [[scope]], который нельзя
получить в явном виде, но он есть
• Каждый вызов var... - всего лишь создает
новое свойство этого объекта, а любое
упоминание переменной - первым делом
ищется в свойствах этого объекта
Замыкания
Обычное выполнение функции без замыкания:
function sum(x,y) {
// неявно создался объект [[scope]]
...
// в [[scope]] записалось свойство z
var z;
// нашли переменную в [[scope]], [[scope]].z = x+y
z = x+y;
// нашли переменную в [[scope]], return [[scope]].z
return z;
// функция закончилась,
// [[scope]] никому больше не нужен и умирает вместе с z
}
Замыкания
Замыкание - это когда объект локальных
переменных [[scope]] внешней функции
остается жить после ее завершения.
Внутренняя функция может обратиться к
нему в любой момент и получить
переменную внешней функции.
Замыкания
Выполнение функции с замыканием:
function addHideHandler(sourceId, targetId) {
// создан объект [[scope]] со свойствами sourceId, targetId
// записать в [[scope]] свойство sourceNode
var sourceNode = document.getElementById(sourceId);
// записать в [[scope]] свойство handler
var handler = function() {
var targetNode = document.getElementById(targetId);
targetNode.style.display = 'none';
};
sourceNode.onclick = handler;
// функция закончила выполнение
// (***) и тут - самое интересное!
}
Замыкания
При запуске функции все происходит стандартно:
1. создается [[scope]]
2. туда записываются локальные переменные
3. внутренняя функция получает ссылку на [[scope]]
Но в самом конце - внутренняя функция присваивается sourceNode.onclick.
Внешняя функция закончила свою работу, но внутренняя - может запуститься
когда-нибудь потом.
Интерпретатор javascript не проводит анализ - понадобятся ли внутренней
функции переменные из внешней, и какие переменные могут быть нужны.
Вместо этого он просто оставляет весь [[scope]] внешней функции в живых.
Чтобы когда внутренняя функция запустится, если она вдруг не найдет какую-либо
переменную в своем [[scope]] - она могла обратиться к [[scope]] внешней функции
и нашла бы ее там.
Замыкания
Пример:
function makeShout() {
var phrase = "Превед!”;
var shout = function() {
alert(phrase);
}
phrase = "Готово!";
return shout;
}
shout = makeShout();
shout(); // что выдаст?
Замыкания
Пример:
function makeShout() {
var phrase = "Превед!”;
var shout = function() {
alert(phrase);
}
phrase = "Готово!";
return shout;
}
shout = makeShout();
shout();
1. создается [[scope]]
2. В [[scope]] пишется: phrase="Превед!”
3. В [[scope]] пишется: shout=..функция..
4. При создании функция shout получает
ссылку на [[scope]] внешней функции
5. [[scope]].phrase меняется на новое значение
"Готово!”
Внутри makeShout()
Замыкания
Пример:
function makeShout() {
var phrase = "Превед!”;
var shout = function() {
alert(phrase);
}
phrase = "Готово!";
return shout;
}
shout = makeShout();
shout();
1. Создается свой собственный объект
[[scope2]]
2. Ищется phrase в [[scope2]] - не найден
3. Ищется phrase в [[scope]] внешней функции -
найдено значение "Готово!”
4. alert("Готово!")
При запуске shout()
То есть, внутренняя функция получает
последнее значение внешних
переменных.
Замыкания
Счетчик:
function makeCounter() {
var numberOfCalls = 0;
return function() {
return ++numberOfCalls;
}
}
var counter1 = makeCounter();
console.log(counter1()); // -> 1
console.log(counter1()); // -> 2
console.log(counter1()); // -> 3
var counter2 = makeCounter();
console.log(counter2()); // -> 1
console.log(counter2()); // -> 2
lambda-функции VS
анонимные функции
• Согласно wiki синонимы
• Есть подозрение что замешан python
lambda х, у: х+у
Почему асинхронность это
сложно?
Callback hell in action
getUser(params["id"], function(err,user) {
if(!user) return res.send(404);
getProfile(user, function(err,profile) {
if(err) return res.send(500);
if(profile) {
update(user,profile,params,function(err) {
if(err) return res.send(500);
res.send(profile);
})
} else {
create(user,params,function(err,profile) {
if(err) return res.send(500);
res.send(profile);
})
}
})
});
Это можно поправить
getUser(params["id"],gotUser);
function gotUser(err,user) {
if(!user) return res.send(404);
// don't inline closure, use bind
getProfile(user,saveProfile.bind(this,user));
}
function saveProfile(user,err,profile) {
if(err) return res.send(500);
if(profile) {
update(user,profile,params,saved);
} else {
create(user,params,saved);
}
}
Выполнение
параллельных задач
var updatedA = false;
var updatedB = false;
updateA(function() {
if(updatedB) done()
updatedA = true;
})
updateB(function() {
if(updatedA) done()
updatedB = true;
})
Когда задач много
var files = [a,b,c,d];
var filtered = [];
var done = 0;
files.forEach(function(file){
something(file, function(passed) {
if(!passed) return;
filtered.push(f);
done += 1;
if(done == files.length) cb();
})
});
Deferred and Promises
Deferred — это отложенный результат,
который станет известен через некоторое
время.
Deferred and Promises
readFile("file.txt", function (err, result) {
// continue here…
});
// becomes
var promiseForResult = readFile("file.txt");
Deferred and Promises
1. Создать Deferred объект
2. При завершении
асинхронного метода
перевести Deferred объект в
нужное состояние
3. Передать Deferred.promise
объект из текущей функции
куда-то, где его состояние
будут отслеживать.
function readFile(fileName){
var deferred = Q.defer();
readFileAsync(fileName, function(error, result){
if(error){
deferred.reject(error);
}else{
deferred.resolve(result);
}
});
return deferred.promise;
}
Инструкция
Почему при возврате из функции
передается не сам Deferred объект, а
именно Promise?
Deferred and Promises
• Deferred объект — это всего лишь хранилище состояния
асинхронной функции. Таких состояний обычно несколько:
– pending — ожидание завершения процесса
– rejected — процесс закончен падением
– resolved — процесс закончен успешно
• Кроме того у Deferred объекта есть ряд методов, которые могут
менять его состояние. Например, метод .resolve().
• По состоянию Deferred объекта мы можем судить, закончен ли
процесс, состояние которого мы отслеживаем.
Deferred and Promises
• Обработчики выполняются последовательно
• Если обработчик «выполнения»/«ошибки» добавляется
к уже «выполненному»/«отменённому» объекту, то он
будет вызван немедленно.
• Повторный вызов resolve/reject не приводт к изменению
состояния и повторному вызову обработчиков, а просто
игнорируется (и не важно, что было вызвано до этого
resolve() или reject()).
• Хотя promises появились в jQuery 1.5 лучше их не юзать
Библиотека Q
• Установка: npm, bower, NuGet
• Модули для: Node.js, CommonJS, AMD,
microjs
• Понимает промисы: jQuery, Dojo, When.js,
WinJS
• Множество сторонних модулей
• mongoose-q, mongo-q
Библиотека Q
• .then, .done, .catch(fail), .finally(fin)
readFile("file.txt")
.then(function(contentOfFile){
// Do something with content
})
.catch(function(error){
// Handle error
})
.finally(function(){
// Call always
})
.done();
Библиотека Q
• .then – выполняем последовательно
readFile("file.txt")
.then(function(contentOfFile){
// Do something with contentOfFile
return readFile("file2.txt")
})
.then(unction(contentOfFile2){
// Do something with contentOfFile2
return readFile("file3.txt")
})
.catch(function(error){
// Error handle
})
.done()
Библиотека Q
• .then – выполняем последовательно
readFile("file.txt")
.then(readFile("file2.txt"))
.then(readFile("file3.txt"))
.catch(function(error){
// Error handle for file, file2 and file3
})
.then(readFile("file4.txt"))
.then(readFile("file5.txt"))
.catch(function(error){
// Error handle for file4 and file5
})
.done()
Библиотека Q
• .when, .all – выполняем параллельно
Q.when(readFile("file.txt"), readFile("file2.txt"))
.catch()
.done()
Q.all([readFile("file.txt"), readFile("file2.txt”])
.catch()
.done()
Библиотека Q
• .spread
Q.all([readFile("file.txt"), readFile("file2.txt”])
.spread(function(contentOfFile, contentOfFile2){
// Do something with contentOfFile1-2
})
.catch()
.done()
getUsername()
.then(function (username) {
return [username, getUser(username)];
})
.spread(function (username, user) {
// do something
})
.catch()
.done();
Библиотека Q
Sequences
var funcs = [foo, bar, baz, qux];
funcs.reduce(Q.when, Q());
Q in Node.js
// 1
Q.nfcall(FS.readFile, "foo.txt", "utf-8");
// 2
var readFile = Q.denodeify(FS.readFile);
return readFile("foo.txt", "utf-8");
// 3
var deferred = Q.defer();
FS.readFile("foo.txt", "utf-8", deferred.makeNodeResolver());
return deferred.promise;
Q and jQuery
Q(jQuery.ajax("foobar.html”))
.then(function (data) {
// on success
})
.catch()
.done()
Вопросы
Ссылочки
Полезно почитать:
• http://bonsaiden.github.io/JavaScript-Garden/
NO MORE PYRAMIDS
• http://timruffles.github.io/reject-js-2013-talk/#/
Lib Q
• https://github.com/kriskowal/q
Мой Github:
• https://github.com/AlexTiTanium

More Related Content

What's hot

Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияYandex
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Dima Dzuba
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»e-Legion
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java scriptViktor Andreev
 
JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаAnton Arhipov
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.Igor Shkulipa
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILRoman Brovko
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковSergey Platonov
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Yauheni Akhotnikau
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9Technopark
 
Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Roman Brovko
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.Roman Brovko
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.Igor Shkulipa
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному кодуVasiliy Deynega
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.Igor Shkulipa
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоStanfy
 

What's hot (20)

Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знания
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8.
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java script
 
JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчика
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GIL
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9
 
Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел Тайкало
 

Similar to Поговорим о JavaScript, основы и современные тенденции развития языка

Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxYandex
 
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
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПKirill Chebunin
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полнойОмские ИТ-субботники
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)Mikhail Davydov
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
Объектное и прототипное программирование в Javascript
Объектное и прототипное программирование в JavascriptОбъектное и прототипное программирование в Javascript
Объектное и прототипное программирование в JavascriptDenis Latushkin
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET Nikita Lipsky
 
JavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработкиJavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработкиGetDev.NET
 
Архитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьАрхитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьAndrey Bibichev
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Pavel Tsukanov
 
Symfony(keremet research)
Symfony(keremet research)Symfony(keremet research)
Symfony(keremet research)Alex Polorotov
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackAlexey Ivanov
 
Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Anton Arhipov
 

Similar to Поговорим о JavaScript, основы и современные тенденции развития языка (20)

Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajax
 
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, Трухин Юрий
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)
 
Javascript 1
Javascript 1Javascript 1
Javascript 1
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Объектное и прототипное программирование в Javascript
Объектное и прототипное программирование в JavascriptОбъектное и прототипное программирование в Javascript
Объектное и прототипное программирование в Javascript
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET
 
JavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработкиJavaScript: хороший тон клиентской разработки
JavaScript: хороший тон клиентской разработки
 
JavaScript как объектно-ориентированный язык программирования
JavaScript как объектно-ориентированный язык программированияJavaScript как объектно-ориентированный язык программирования
JavaScript как объектно-ориентированный язык программирования
 
Архитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьАрхитектура в Agile: слабая связность
Архитектура в Agile: слабая связность
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?
 
PowerShell
PowerShellPowerShell
PowerShell
 
Symfony(keremet research)
Symfony(keremet research)Symfony(keremet research)
Symfony(keremet research)
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpack
 
Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101
 

Поговорим о JavaScript, основы и современные тенденции развития языка

  • 1. О себе Александр Кучеренко • В DataArt 1,5 месяца • Занимаюсь программированием 7+ лет • За это время писал на: PHP, JavaScript, ActionScript3, C#, Java(Android), Objective-C
  • 2. Поговорим о JavaScript 1. Объекты в JavaScript, лямбды, замыкания. 2. Deferred & Promises. 3. Библиотека Q.
  • 3. С чего начиналось С чего все начиналось: • Ajax • Web 2.0 • jQuery
  • 4. Что сейчас • Полноценные веб приложения (GoogleDoc, eyeOs, FirefoxOS, ChromeOS) • Мобильные приложения (PhoneGap, jQuery Mobile, Sencha Touch) • Серверный JavaScript (Node JS) • Инструменты (MongoDB, JSON, NPM, Bower, Grunt) • Тестирование: Buster.js, Karma, TestSwarm, JsTestDriver, YUI Yeti, Jasmine, QUnit, Sinon • 3D графика WebGL
  • 5. Базовые типы Элементарные • Number • Boolean • String • Null • undefined String Array Date Объекты Function …
  • 6. Number • Float64 - 8 байт • console.log(0.1+0.2) > 0.3 ? > 0.30000000000000004 • BCMath for JavaScript • 0.1234.toFixed(2) = 0.12
  • 7. Number • При операциях с Number - никогда не происходят ошибки. Зато могут быть возвращены специальные значения • 1/0 = Number.POSITIVE_INFINITY (плюс бесконечность) • -1/0 = Number.NEGATIVE_INFINITY (минус бесконечность) • Положительная бесконечность Number.POSITIVE_INFINITY больше любого Number, и даже больше самой себя.
  • 8. Number • NaN - особый результат • Любая математическая операция с NaN дает NaN: – NaN + 1 = NaN • NaN не равен сам себе: – NaN == NaN // false • Можно проверить с помощью функции isNaN: – isNaN(NaN) // true
  • 9. String • Строки в javascript - полностью юникодные • Кавычки двойные и одинарные работают одинаково • Можно указывать юникодные символы через uXXXX: • Встроены регулярные выражения, методы replace/match: "превед медвед".replace(/(.*?)s(.*)/, "$2, $1!") // => медвед, превед!
  • 10. Boolean • False – false – null – undefined – “” – 0 – Number.NaN • True – все остальное – “0” (В PHP FALSE) – “false”
  • 11. undefined • При попытке доступа к глобальной переменной undefined (если она не изменена). • Неявный возврат из функции при отсутствии в ней оператора return. • Из операторов return, которые ничего не возвращают. • В результате поиска несуществующего свойства у объекта (и доступа к нему). • Параметры, которые не были переданы в функцию явно. • При доступе ко всему, чьим значением является undefined.
  • 12. undefined • undefined — это тип с единственным возможным значением: undefined • Не являясь константой, она не является и ключевым словом. Можно с лёгкостью переопределить // Happy debugging suckers ... undefined = true; (function(something, foo, undefined) { // в локальной области видимости `undefined` // снова ссылается на правильное значене. })('Hello World', 42);
  • 13. NULL • Используется во внутренних механизмах JavaScript (например для определения конца цепочки прототипов за счёт присваивания Foo.prototype = null)
  • 14. Объекты • В JavaScript всё ведет себя, как объект, лишь за двумя исключениями — NULL и UNDEFINED. • Почему у примитивов можно вызвать методы?
  • 15. Объекты и примитивы var number = 2; // Можно вызвать метод console.log(number.toString()); // -> 2 // Попробуем задать свойство number.newProperty = 3; console.log(number.newProperty); // -> undefined // Если нельзя, но сильно хочется, то - можно Number.prototype.newProperty = 3; console.log(number.newProperty); // -> 3
  • 16. Function • Функции в JavaScript тоже являются объектами Пример №1: foo(); // сработает, т.к. функция будет создана до выполнения кода function foo() {} Пример №2: foo; // 'undefined' foo(); // вызовет TypeError var foo = function() {};
  • 17. Область видимости Пример №1: function test() { // область видимости for(var i = 0; i < 10; i++) { // не область видимости // считаем } console.log(i); // 10 } Хотя JavaScript нормально понимает синтаксис двух фигурных скобок, окружающих блок, он не поддерживает блочную область видимости; всё что остаётся на этот случай в языке — область видимости функций.
  • 18. Как работает this 1. Глобальная область видимости Когда мы используем this в глобальной области, она будет просто ссылаться на глобальный объект. Различают ровно пять вариантов того, к чему привязывается this в языке. 4. Вызов конструктора new foo(); Если перед вызовом функции присутствует ключевое слово new то данная функция будет действовать как конструктор. Внутри такой функции this будет указывать на новосозданный Object. 2. Вызов функции foo(); // Тут this также ссылается на глобальный объект 3. Вызов метода test.foo(); // Тут this также ссылается на глобальный объект.
  • 19. Как работает this 5. Переопределение this Переопределить this можно с помощью методов apply, call и bind Пример №1: function foo(a, b, c) {} var bar = {}; foo.apply(bar, [1, 2, 3]); // массив развернётся в a = 1, b = 2, c = 3 foo.call(bar, 1, 2, 3); // аналогично
  • 20. Как работает this Пример самой распространённой ошибки: Foo.method = function() { function test() { // this ??? } test(); }
  • 21. Как работает this Пример самой распространённой ошибки: Foo.method = function() { function test() { // this ссылается на глобальный объект } test(); }
  • 22. Как работает this Достойно выходим из ситуации: Foo.method = function() { var that = this; function test() { // Здесь используем that вместо this } test(); }
  • 23. Как работает this А что если… var test = someObject.methodTest; test();
  • 24. Как работает this А что если… var test = someObject.methodTest; test(); Следуя первому правилу test вызывается как обычная функция; следовательно this внутри него больше не ссылается на someObject Хотя позднее связывание this на первый взгляд может показаться плохой идеей, но на самом деле именно благодаря этому работает наследование прототипов.
  • 25. Замыкания Замыкание в JavaScript: function outerFn(myArg) { var myVar = 42; function innerFn() { // имеет доступ к myVar и myArg } }
  • 26. Замыкания Замыкание в PHP: function getNumber() { $id = 42; return function() use ($id){ return $id*2; }; }
  • 27. Замыкания Классика: for(var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); } , 1000);}
  • 28. Замыкания • Каждое выполнение функции хранит все переменные в специальном объекте с кодовым именем [[scope]], который нельзя получить в явном виде, но он есть • Каждый вызов var... - всего лишь создает новое свойство этого объекта, а любое упоминание переменной - первым делом ищется в свойствах этого объекта
  • 29. Замыкания Обычное выполнение функции без замыкания: function sum(x,y) { // неявно создался объект [[scope]] ... // в [[scope]] записалось свойство z var z; // нашли переменную в [[scope]], [[scope]].z = x+y z = x+y; // нашли переменную в [[scope]], return [[scope]].z return z; // функция закончилась, // [[scope]] никому больше не нужен и умирает вместе с z }
  • 30. Замыкания Замыкание - это когда объект локальных переменных [[scope]] внешней функции остается жить после ее завершения. Внутренняя функция может обратиться к нему в любой момент и получить переменную внешней функции.
  • 31. Замыкания Выполнение функции с замыканием: function addHideHandler(sourceId, targetId) { // создан объект [[scope]] со свойствами sourceId, targetId // записать в [[scope]] свойство sourceNode var sourceNode = document.getElementById(sourceId); // записать в [[scope]] свойство handler var handler = function() { var targetNode = document.getElementById(targetId); targetNode.style.display = 'none'; }; sourceNode.onclick = handler; // функция закончила выполнение // (***) и тут - самое интересное! }
  • 32. Замыкания При запуске функции все происходит стандартно: 1. создается [[scope]] 2. туда записываются локальные переменные 3. внутренняя функция получает ссылку на [[scope]] Но в самом конце - внутренняя функция присваивается sourceNode.onclick. Внешняя функция закончила свою работу, но внутренняя - может запуститься когда-нибудь потом. Интерпретатор javascript не проводит анализ - понадобятся ли внутренней функции переменные из внешней, и какие переменные могут быть нужны. Вместо этого он просто оставляет весь [[scope]] внешней функции в живых. Чтобы когда внутренняя функция запустится, если она вдруг не найдет какую-либо переменную в своем [[scope]] - она могла обратиться к [[scope]] внешней функции и нашла бы ее там.
  • 33. Замыкания Пример: function makeShout() { var phrase = "Превед!”; var shout = function() { alert(phrase); } phrase = "Готово!"; return shout; } shout = makeShout(); shout(); // что выдаст?
  • 34. Замыкания Пример: function makeShout() { var phrase = "Превед!”; var shout = function() { alert(phrase); } phrase = "Готово!"; return shout; } shout = makeShout(); shout(); 1. создается [[scope]] 2. В [[scope]] пишется: phrase="Превед!” 3. В [[scope]] пишется: shout=..функция.. 4. При создании функция shout получает ссылку на [[scope]] внешней функции 5. [[scope]].phrase меняется на новое значение "Готово!” Внутри makeShout()
  • 35. Замыкания Пример: function makeShout() { var phrase = "Превед!”; var shout = function() { alert(phrase); } phrase = "Готово!"; return shout; } shout = makeShout(); shout(); 1. Создается свой собственный объект [[scope2]] 2. Ищется phrase в [[scope2]] - не найден 3. Ищется phrase в [[scope]] внешней функции - найдено значение "Готово!” 4. alert("Готово!") При запуске shout() То есть, внутренняя функция получает последнее значение внешних переменных.
  • 36. Замыкания Счетчик: function makeCounter() { var numberOfCalls = 0; return function() { return ++numberOfCalls; } } var counter1 = makeCounter(); console.log(counter1()); // -> 1 console.log(counter1()); // -> 2 console.log(counter1()); // -> 3 var counter2 = makeCounter(); console.log(counter2()); // -> 1 console.log(counter2()); // -> 2
  • 37. lambda-функции VS анонимные функции • Согласно wiki синонимы • Есть подозрение что замешан python lambda х, у: х+у
  • 39. Callback hell in action getUser(params["id"], function(err,user) { if(!user) return res.send(404); getProfile(user, function(err,profile) { if(err) return res.send(500); if(profile) { update(user,profile,params,function(err) { if(err) return res.send(500); res.send(profile); }) } else { create(user,params,function(err,profile) { if(err) return res.send(500); res.send(profile); }) } }) });
  • 40. Это можно поправить getUser(params["id"],gotUser); function gotUser(err,user) { if(!user) return res.send(404); // don't inline closure, use bind getProfile(user,saveProfile.bind(this,user)); } function saveProfile(user,err,profile) { if(err) return res.send(500); if(profile) { update(user,profile,params,saved); } else { create(user,params,saved); } }
  • 41. Выполнение параллельных задач var updatedA = false; var updatedB = false; updateA(function() { if(updatedB) done() updatedA = true; }) updateB(function() { if(updatedA) done() updatedB = true; })
  • 42. Когда задач много var files = [a,b,c,d]; var filtered = []; var done = 0; files.forEach(function(file){ something(file, function(passed) { if(!passed) return; filtered.push(f); done += 1; if(done == files.length) cb(); }) });
  • 43. Deferred and Promises Deferred — это отложенный результат, который станет известен через некоторое время.
  • 44. Deferred and Promises readFile("file.txt", function (err, result) { // continue here… }); // becomes var promiseForResult = readFile("file.txt");
  • 45. Deferred and Promises 1. Создать Deferred объект 2. При завершении асинхронного метода перевести Deferred объект в нужное состояние 3. Передать Deferred.promise объект из текущей функции куда-то, где его состояние будут отслеживать. function readFile(fileName){ var deferred = Q.defer(); readFileAsync(fileName, function(error, result){ if(error){ deferred.reject(error); }else{ deferred.resolve(result); } }); return deferred.promise; } Инструкция Почему при возврате из функции передается не сам Deferred объект, а именно Promise?
  • 46. Deferred and Promises • Deferred объект — это всего лишь хранилище состояния асинхронной функции. Таких состояний обычно несколько: – pending — ожидание завершения процесса – rejected — процесс закончен падением – resolved — процесс закончен успешно • Кроме того у Deferred объекта есть ряд методов, которые могут менять его состояние. Например, метод .resolve(). • По состоянию Deferred объекта мы можем судить, закончен ли процесс, состояние которого мы отслеживаем.
  • 47. Deferred and Promises • Обработчики выполняются последовательно • Если обработчик «выполнения»/«ошибки» добавляется к уже «выполненному»/«отменённому» объекту, то он будет вызван немедленно. • Повторный вызов resolve/reject не приводт к изменению состояния и повторному вызову обработчиков, а просто игнорируется (и не важно, что было вызвано до этого resolve() или reject()). • Хотя promises появились в jQuery 1.5 лучше их не юзать
  • 48. Библиотека Q • Установка: npm, bower, NuGet • Модули для: Node.js, CommonJS, AMD, microjs • Понимает промисы: jQuery, Dojo, When.js, WinJS • Множество сторонних модулей • mongoose-q, mongo-q
  • 49. Библиотека Q • .then, .done, .catch(fail), .finally(fin) readFile("file.txt") .then(function(contentOfFile){ // Do something with content }) .catch(function(error){ // Handle error }) .finally(function(){ // Call always }) .done();
  • 50. Библиотека Q • .then – выполняем последовательно readFile("file.txt") .then(function(contentOfFile){ // Do something with contentOfFile return readFile("file2.txt") }) .then(unction(contentOfFile2){ // Do something with contentOfFile2 return readFile("file3.txt") }) .catch(function(error){ // Error handle }) .done()
  • 51. Библиотека Q • .then – выполняем последовательно readFile("file.txt") .then(readFile("file2.txt")) .then(readFile("file3.txt")) .catch(function(error){ // Error handle for file, file2 and file3 }) .then(readFile("file4.txt")) .then(readFile("file5.txt")) .catch(function(error){ // Error handle for file4 and file5 }) .done()
  • 52. Библиотека Q • .when, .all – выполняем параллельно Q.when(readFile("file.txt"), readFile("file2.txt")) .catch() .done() Q.all([readFile("file.txt"), readFile("file2.txt”]) .catch() .done()
  • 53. Библиотека Q • .spread Q.all([readFile("file.txt"), readFile("file2.txt”]) .spread(function(contentOfFile, contentOfFile2){ // Do something with contentOfFile1-2 }) .catch() .done() getUsername() .then(function (username) { return [username, getUser(username)]; }) .spread(function (username, user) { // do something }) .catch() .done();
  • 54. Библиотека Q Sequences var funcs = [foo, bar, baz, qux]; funcs.reduce(Q.when, Q());
  • 55. Q in Node.js // 1 Q.nfcall(FS.readFile, "foo.txt", "utf-8"); // 2 var readFile = Q.denodeify(FS.readFile); return readFile("foo.txt", "utf-8"); // 3 var deferred = Q.defer(); FS.readFile("foo.txt", "utf-8", deferred.makeNodeResolver()); return deferred.promise;
  • 56. Q and jQuery Q(jQuery.ajax("foobar.html”)) .then(function (data) { // on success }) .catch() .done()
  • 58. Ссылочки Полезно почитать: • http://bonsaiden.github.io/JavaScript-Garden/ NO MORE PYRAMIDS • http://timruffles.github.io/reject-js-2013-talk/#/ Lib Q • https://github.com/kriskowal/q Мой Github: • https://github.com/AlexTiTanium