Михаил Давыдов: javascript. Базовые знания

72

Upload: yandex

Post on 16-Jun-2015

4.184 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: Михаил Давыдов: JavaScript. Базовые знания
Page 2: Михаил Давыдов: JavaScript. Базовые знания

Михаил Давыдов Разработчик JavaScript

JavaScript Базовые знания

Page 3: Михаил Давыдов: JavaScript. Базовые знания

Базовый синтаксис

Expression (Выражение, Оператор),

Statement (Блочное выражение, Блок)

Page 4: Михаил Давыдов: JavaScript. Базовые знания

4

Statement

• Блочное выражение –  if (){}, try{}catch(e){}, function a(){}

•  Директива интерпретатору –  return, throw, break, continue, var, …

• Может включать другие блочные выражения • Может включать выражения • Не возвращает значение • Не может быть аргументом Expression • Можно сделать из Expression – Expression;

http://es5.github.com/#x12

Page 5: Михаил Давыдов: JavaScript. Базовые знания

5

Expression

• Оператор –  С одним аргументом typeof, !, (), ++, --, new, +,… –  С двумя ==, ===, >, <, instanceof, +, -,… –  С тремя a?b:c,… –  Вызов функции –  Оператор запятая

• Может включать другие операторы • Не может включать Statement • Возвращает значение • Может быть в составе Statement

http://es5.github.com/#x11

Page 6: Михаил Давыдов: JavaScript. Базовые знания

Приведение типов

Page 7: Михаил Давыдов: JavaScript. Базовые знания

7

Приведение типов

• Зависит от оператора –  Оператор имеет определенный алгоритм

• Зависит от типа аргументов • Внутренние функции JavaScript

–  ToNumber, ToString, ToBoolean, ToObject

Page 8: Михаил Давыдов: JavaScript. Базовые знания

8

Сильно перегружен: сложение чисел, конкатенация строк

"2" + 3; // "23" 2 + 3; // 5

Пример: оператор + и примитивы

// Что происходит в внутренностях JavaScript a = ToPrimitive(a); b = ToPrimitive(b); if (Type(a) === "String" || Type(b) === "String") { return Concat(ToString(a), ToString(b)); } else { return ToNumber(2) + ToNumber(3); } http://es5.github.com/#x11.6.1

Page 9: Михаил Давыдов: JavaScript. Базовые знания

9

Что если один из операндов – Object?

Page 10: Михаил Давыдов: JavaScript. Базовые знания

10

Применяется тот же алгоритм Вся «магия» в ToString({})

"2" + {}; // "2[object Object]"

Пример: оператор + объект

Concat(ToString("2"), ToString({})); ToString({}) -> ToPrimitive({}, "String") ToPrimitive({}, "String") -> ({}).[[DefaultValue]]("String")

http://es5.github.com/#x8.12.8

Page 11: Михаил Давыдов: JavaScript. Базовые знания

11

Применяется тот же алгоритм Вся «магия» в ToString({})

Пример: оператор + объект

if (IsCallable({}.toString)) { return ({}).toString(); } else if (IsCallable({}.valueOf)) { return ({}). valueOf(); } else { throw new TypeError(); }

http://es5.github.com/#x8.12.8

Page 12: Михаил Давыдов: JavaScript. Базовые знания

12

[]+{}

Page 13: Михаил Давыдов: JavaScript. Базовые знания

13

The Abstract Equality Comparison Algorithm

Операторы == и ===

'' == '0' // false 0 == '' // true 0 == '0' // true false == undefined // false false == null // false null == undefined // true

http://es5.github.com/#x11.9.3

Page 14: Михаил Давыдов: JavaScript. Базовые знания

14

'' === '0' // false 0 === '' // false 0 === '0' // false false === undefined // false false === null // false null === undefined // false +0 === -0 // true

Операторы == и === The Strict Equality Comparison Algorithm

http://es5.github.com/#x11.9.6

Page 15: Михаил Давыдов: JavaScript. Базовые знания

15

Оператор typeof

Type(val) Результат Undefined "undefined" Null "object" Boolean "boolean" Number "number" String "string" Object "object" Object и имеет [[Call]] "function”

http://es5.github.com/#x11.4.3

Алгоритм - Ссылка не достижима (IsUnresolvableReference) – возвращаем "undefined" - Иначе смотрим по таблице

Page 16: Михаил Давыдов: JavaScript. Базовые знания

16

WAT?

• [1] > 0; // ? • [1,1] > 0; // ? • [1,] > 0; // ? • [1,,] > 0; // ?

• [1] > "0"; // ?

Page 17: Михаил Давыдов: JavaScript. Базовые знания

17

WAT?

• [1] > 0; // true • [1,1] > 0; // false • [1,] > 0; // true • [1,,] > 0; // false

• [1] > "0"; // ?

Page 18: Михаил Давыдов: JavaScript. Базовые знания

Функции

Function Declaration,

Conditional Function Declaration,

Function Expression,

Named Function Expression,

IEFE

Page 19: Михаил Давыдов: JavaScript. Базовые знания

19

На самом деле Function в JavaScript – это Object со скрытым полем [[Call]]

http://es5.github.com/#x13.2

Page 20: Михаил Давыдов: JavaScript. Базовые знания

20

- Это Statement - Инициализируется во время входа в контекст - Объявляется в блоке функции или в глобальном блоке

a(); // OK function a() { b(); // OK function b() { } } a();

Function Declaration/Definition

http://es5.github.com/#x13

Page 21: Михаил Давыдов: JavaScript. Базовые знания

21

- Это тоже Statement - Инициализируется во время входа в контекст или в рантайме - По стандарту такая запись недопустима

if (true) { function a() { return 1; } } else { function a() { return 2; } } a(); // Firefox – 1, Others - 2

Conditional Function Declaration

Page 22: Михаил Давыдов: JavaScript. Базовые знания

22

- При использовании строгого режима тут будет SyntaxError

"use strict"; if (true) { function a() { return 1; } } else { function a() { return 2; } } // SyntaxError // Use Function Expression!

CFD+Strict Mode

Page 23: Михаил Давыдов: JavaScript. Базовые знания

23

- Это expression - Инициализируется в рантайме - Объявляется где угодно

a(); // error var a = function () { b(); // error var b = function () {}; b(); // ok }; a(); // ok

Function Expression

http://es5.github.com/#x11.2.5

Page 24: Михаил Давыдов: JavaScript. Базовые знания

24

- Это тот же Function Expression - Можно обратиться к себе по своему имени - Имя доступно только в своем блоке (кроме старых IE)

(function timer() { setTimeout(timer, 1000); console.log(+new Date); }()); typeof timer; // undefined, Old IE - function

Named Function Expression

Page 25: Михаил Давыдов: JavaScript. Базовые знания

25

- Это тот же Function Expression -  Мы даем понять интерпретатору, что этот код - Function Expression -  IEFE позволяет эмулировать блочную область видимости

function (){}(); // SyntaxError !function (){}(); // OK +function (){}(); // OK *function (){}(); // OK (function (){}()); // OK [function (){}()]; // OK var a = function (){}(); var a = (function (){}()); // The best

IEFE

Page 26: Михаил Давыдов: JavaScript. Базовые знания

Область видимости

Определяется во время создания функции

Не меняется при передаче функции

Образует цепочку областей видимости

Лексическая

Образует «замыкание»

Page 27: Михаил Давыдов: JavaScript. Базовые знания

27

var a = 1; function foo() { var c = 2; function bar(e) { return a + c + e; } return bar(3); } foo(); // 6

Область видимости

http://es5.github.com/#x10.3 http://es5.github.com/#x10.2

Page 28: Михаил Давыдов: JavaScript. Базовые знания

28

Цепочка областей видимости

GLOBAL a 1 foo func(on

foo c 2 bar func(on

bar e argument

Page 29: Михаил Давыдов: JavaScript. Базовые знания

Вызов функции и this

this – основная грабля в JavaScript

Прямой вызов

Вызов через c оператором точка и []

Вызов через new

Вызов через call, apply, bind

Page 30: Михаил Давыдов: JavaScript. Базовые знания

30

This в JavaScript определяется во время вызова функции!

http://es5.github.com/#x11.2.3

Page 31: Михаил Давыдов: JavaScript. Базовые знания

31

() – это оператор вызова функции this всегда undefined но он трансформируется в global В строгом режиме всегда undefined (трансформации нет)

function a() { console.log(this); } a(); // window (undefined -> window) function b() { "use strict"; console.log(this); } b(); // undefined

Прямой вызов – через оператор ()

Page 32: Михаил Давыдов: JavaScript. Базовые знания

32

Это Expression this – объект от которого был получена эта функция

var foo = { bar: function () { console.log(this); } }; foo.bar(); // foo var baz = {}; baz.bar = foo.bar; baz.bar(); // baz var fooBar = foo.bar; fooBar(); // ???

Вызов функции и оператор . и []

http://es5.github.com/#x11.2.1

Page 33: Михаил Давыдов: JavaScript. Базовые знания

33

Это Expression new – это еще один способ вызова функции Каждая функция может быть конструктором this – пустой объект со ссылкой на prototype вызываемой функции

var A = function () { console.log(this); console.log( this.__proto__ === A.prototype ); }; new A(); // Object, true

Оператор new

http://es5.github.com/#x11.2.2

Page 34: Михаил Давыдов: JavaScript. Базовые знания

34

Это способ управлять значением this this – объект, который вы передаете

var a = function (a, b) { console.log(this, a, b); }; a.call([]); // [], undefined, … a.call([], 1, 2); // [], 1, 2 a.apply([], [1, 2]); // [], 1, 2

Call, apply

http://es5.github.com/#x15.3.4.4 http://es5.github.com/#x15.3.4.3

Page 35: Михаил Давыдов: JavaScript. Базовые знания

35

Это способ подменять this без вызова функции this – объект, который вы передаете

var a = function () { console.log(this); }; var b = a.bind({}); b(); // {}

Bind

http://es5.github.com/#x15.3.4.5 MDN Function#bind http://clck.ru/2EeTx

Page 36: Михаил Давыдов: JavaScript. Базовые знания

Вызов функции, arguments

Передача значения

arguments

Page 37: Михаил Давыдов: JavaScript. Базовые знания

37

Передача значения в функцию

• Значения передаются по ссылке • Можно менять «поля» переданного объекта • Примитив менять нельзя • Можно переписать ссылку без потери объекта

Page 38: Михаил Давыдов: JavaScript. Базовые знания

38

arguments

• Как и this появляется при вызове • Это не Array • Содержит список всех аргументов

–  arguments[0]…

• Содержит ссылку на вызывающий конекст –  arguments.caller –  Deprecated!

• Содержит ссылку на себя –  arguments.calle

http://es5.github.com/#x10.6

Page 39: Михаил Давыдов: JavaScript. Базовые знания

Прототипное наследование

prototype и __proto__,

Цепочка прототипов,

Оператор получения свойства,

Оператор instanceof,

Оператор new

Page 40: Михаил Давыдов: JavaScript. Базовые знания

40

Сказка о мутантах

Page 41: Михаил Давыдов: JavaScript. Базовые знания

41

Сказка о мутантах

• В далекой-далекой галактике • Нет привычного нам наследования • Есть телепатическое наследование

–  "Телегенез"

• Действующие лица: –  Дедушка –  Отец –  Сын

Page 42: Михаил Давыдов: JavaScript. Базовые знания

42

Структура мутанта

Мутант

"Телепатические" гены

Собственные гены

Движение генов

Page 43: Михаил Давыдов: JavaScript. Базовые знания

43

Все зеленые

Color  

Дед Отец Сын

Page 44: Михаил Давыдов: JavaScript. Базовые знания

44

Дед: хочу стать синим!

Color  

Дед Отец Сын

Page 45: Михаил Давыдов: JavaScript. Базовые знания

45

Все посинели

Color  

Дед Отец Сын

Page 46: Михаил Давыдов: JavaScript. Базовые знания

46

Отец: верну-ка я цвет

Color   Color  

Дед Отец Сын

Page 47: Михаил Давыдов: JavaScript. Базовые знания

47

Дед синий, отец и сын зеленые

Color   Color  

Дед Отец Сын

Page 48: Михаил Давыдов: JavaScript. Базовые знания

48

Сын: хочу быть черным

Color  

Color   Color  

Дед Отец Сын

Page 49: Михаил Давыдов: JavaScript. Базовые знания

49

Мутанты и JavaScript

Size,  Age  

Color  

Объект

Свойства прототипа

Собственные свойства

Делегирование

Цепочка прототипов

Page 50: Михаил Давыдов: JavaScript. Базовые знания

50

Собственные свойства и прототип

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

–  И примитив также* –  Имеет с рождения –  По умолчанию – Object.prototype

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

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

Page 51: Михаил Давыдов: JavaScript. Базовые знания

51

prototype и __proto__

• prototype – свойство функции –  Оно есть у функции с рождения –  По умолчанию это пустой объект

• __proto__ – ссылка на prototype у объекта –  Во многих движках JavaScript оно скрыто –  Определяется во время работы оператора new

http://es5.github.com/#x15.3.5.2 http://es5.github.com/#x8.6.2

Page 52: Михаил Давыдов: JavaScript. Базовые знания

52

Цепочка прототипов это способ наследования в JavaScript

Page 53: Михаил Давыдов: JavaScript. Базовые знания

53

Работа оператора new

• new(Constructor, arguments):*!• Получает на вход 2 операнда

–  Функция должна иметь свойство prototype

• Создает временный объект (obj) • Добавляет свойство __proto__

–  obj.__proto__ = Constructor.prototype

• Вызывает конструктор над объектом –  Constructor.apply(obj, arguments)

• Конструктор вернул примитив. Результат obj • Иначе то, что вернул конструктор

Page 54: Михаил Давыдов: JavaScript. Базовые знания

54

function myNew(Constructor, args) { if (typeof Constructor !== "function") { throw new TypeError(); } if (typeof Constructor.prototype === "undefined") { throw new TypeError(); } var obj = { __proto__: Constructor.prototype }; var result = Constructor.apply(obj, args); if (typeof result === "object" && result !== null || typeof result === "function") { return result; } return obj; }

Оператор new в коде

Page 55: Михаил Давыдов: JavaScript. Базовые знания

55

Цепочка прототипов

// Конструктор Grandfather var Grandfather = function () {}; Grandfather.prototype.color = 'green';

// Конструктор Father var Father = function () {}; typeof Father.prototype === 'object';

// Для цепочки нам нужно получить вот это Father.prototype = { __proto__: Grandfather.prototype };

Page 56: Михаил Давыдов: JavaScript. Базовые знания

56

Строим цепочку прототипов явно

// Конструктор Father var Father = function () {}; Father.prototype = new Grandfather();

// Как помним, это аналогично: Father.prototype = { __proto__: Grandfather.prototype };

Page 57: Михаил Давыдов: JavaScript. Базовые знания

57

Оператор new используется для построения цепочек прототипов

Page 58: Михаил Давыдов: JavaScript. Базовые знания

58

Оператор . и []

• Выполняет поиск свойства • Использует цепочку прототипов • Ищет в собственных свойствах • Затем рекурсивно по ссылке __proto__ • Если __proto__ null – возвратит undefined

http://es5.github.com/#x11.2.1

Page 59: Михаил Давыдов: JavaScript. Базовые знания

59

var Foo = function () { // Собственное свойство this.b = 146; }; Foo.prototype.bar = function () { console.log(this); }; Foo.prototype.a = 123;

Оператор . и []

Page 60: Михаил Давыдов: JavaScript. Базовые знания

60

var foo = new Foo(); foo.__ptoto__ === Foo.prototype;

Оператор . и []

Page 61: Михаил Давыдов: JavaScript. Базовые знания

61

Оператор . и []

foo b 146 __proto__ object

Foo.prototype bar function a 123 __proto__ object

Object.prototype __proto__ null

http://es5.github.com/#x4.2.1

Page 62: Михаил Давыдов: JavaScript. Базовые знания

62

var foo = new Foo(); foo.__ptoto__ === Foo.prototype; foo.bar(); // foo foo.a; // 123 foo['b']; // 146 foo.c; // undefined Foo.prototype.c = 8; foo.c; // 8 <- Magic???

Оператор . и []

Page 63: Михаил Давыдов: JavaScript. Базовые знания

63

Оператор instanceof

• Использует цепочку прототипов • Рекурсивно ищет __proto__ === prototype

Page 64: Михаил Давыдов: JavaScript. Базовые знания

64

var Foo = function () { this.b = 146; }; var foo = new Foo(); foo instanceof Foo; // true foo instanceof Object; // true foo instanceof Array; // false

Оператор instanceof

http://es5.github.com/#x11.8.6

Page 65: Михаил Давыдов: JavaScript. Базовые знания

65

Цепочка прототипов

foo b 146 __proto__ object

Foo.prototype bar function a 123 __proto__ object

Object.prototype __proto__ null

Page 66: Михаил Давыдов: JavaScript. Базовые знания

66

var Foo = function () { this.b = 146; }; var foo = new Foo(); Foo.prototype.__proto__ = Array.prototype; foo instanceof Array; // true (!)

Оператор instanceof

http://es5.github.com/#x11.8.6

Page 67: Михаил Давыдов: JavaScript. Базовые знания

67

Цепочка прототипов

foo b 146 __proto__ object

Foo.prototype bar function a 123 __proto__ object

Array.prototype __proto__ object

Object.prototype __proto__ null

Page 68: Михаил Давыдов: JavaScript. Базовые знания

Strict Mode

На самоподготовку

- выделите отличия от обычного режима

- всегда ли стоит применять Strict Mode?

- в каком месте кода стоит объявлять SM?

http://es5.github.com/#x10.1.1

Page 69: Михаил Давыдов: JavaScript. Базовые знания

Annotated ECMAScript 5.1

http://es5.github.com/

Page 70: Михаил Давыдов: JavaScript. Базовые знания

Mozilla Developer Network

https://developer.mozilla.org/en-US/

Page 71: Михаил Давыдов: JavaScript. Базовые знания

Основы и заблуждения насчет JavaScript

http://habrahabr.ru/post/120193/

Page 72: Михаил Давыдов: JavaScript. Базовые знания

Михаил Давыдов

Разработчик JavaScript

[email protected] azproduction

Спасибо