javascript. loops and functions (in russian)

59

Upload: mikhail-davydov

Post on 16-Jun-2015

216 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: JavaScript. Loops and functions (in russian)
Page 2: JavaScript. Loops and functions (in russian)

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

JavaScript Циклы и Функции

Page 3: JavaScript. Loops and functions (in russian)

Циклы – Statements

for,

while,

do while,

for in

Page 4: JavaScript. Loops and functions (in russian)

for, while, do while – работают так же как и во всех языках. Ура!

Page 5: JavaScript. Loops and functions (in russian)

for in

• Можно итерировать поля объекта • Пробегает по перечисляемым свойствам

–  По собственным свойствам –  И по свойствам прототипа

• Перечисляемость – скрытое свойство

Page 6: JavaScript. Loops and functions (in russian)

6

var obj = { a: 1, b: {}, c: 'ololo' }; for (var keyName in obj) { console.log(keyName + ': ' + obj[keyName]); } // Результат "a: 1" "b: [object Object]" "c: 'ololo'" typeof obj.toString === "function"; // Почему его нет? typeof obj.hasOwnProperty === "function"; // Почему его нет?

for in: Пример

Page 7: JavaScript. Loops and functions (in russian)

7

hasOwnProperty и toString и др. – не перечисляемые свойства

Page 8: JavaScript. Loops and functions (in russian)

8

// А что если? Object.prototype.toString = function () {};

Page 9: JavaScript. Loops and functions (in russian)

9

Если toString и другие переписать, то они станут уже перечисляемыми

Page 10: JavaScript. Loops and functions (in russian)

10

var Constructor = function () {}; Constructor.prototype.myValue = 123; var obj = new Constructor(); obj.a = 1; obj.b = {}; obj.c = 'ololo'; for (var keyName in obj) { console.log(keyName + ': ' + obj[keyName]); } // Результат "a: 1" "b: [object Object]" "c: 'ololo'" "myValue: 123" // <<< ????

for in: Пример с загрязнением

Page 11: JavaScript. Loops and functions (in russian)

11

myValue – перечисляемое, но не собственное свойство

Page 12: JavaScript. Loops and functions (in russian)

12

var Constructor = function () {}; Constructor.prototype.myValue = 123; var obj = new Constructor(); obj.a = 1; obj.b = {}; obj.c = 'ololo'; for (var keyName in obj) { if (obj.hasOwnProperty(keyName)) { console.log(keyName + ': ' + obj[keyName]); } } // Результат "a: 1" "b: [object Object]" "c: 'ololo'"

for in: Пример c hasOwnProperty

Page 13: JavaScript. Loops and functions (in russian)

Циклы Expressions

forEach

map

every, some

filter

reduce, reduceRight

Page 14: JavaScript. Loops and functions (in russian)

Как правило все циклы связаны с массивом

Page 15: JavaScript. Loops and functions (in russian)

Почему бы тогда не добавить итераторов к Array?!

Page 16: JavaScript. Loops and functions (in russian)

var persons = [{ "name": "Ann", "age": 21 }, { "name": "Helen", "age": 16 }, { "name": "Peter", "age": 76 }, { "name": "Jack", "age": 12 }];

Пример

Page 17: JavaScript. Loops and functions (in russian)

persons.forEach(): Undefined

Page 18: JavaScript. Loops and functions (in russian)

// Слишком много шума и лишних слов for (var i = 0; i < persons.length; i++) { console.log(persons[i].name[0]); } // "A", "H", "P", "J" // Лучше, чище, нагляднее persons.forEach(function (person) { console.log(person.name[0]); }); // "A", "H", "P", "J"

forEach(): вывести 1 букву имени

Page 19: JavaScript. Loops and functions (in russian)

persons.map(): Array

Page 20: JavaScript. Loops and functions (in russian)

var result = []; // Слишком много шума и лишних слов for (var i = 0; i < persons.length; i++) { result.push(persons[i].name); } console.log(result); // ["Ann", "Helen", "Peter", "Jack"] // Лучше, чище, нагляднее var result = persons.map(function (person) { return person.name; }); console.log(result); // ["Ann", "Helen", "Peter", "Jack"]

map(): получить только имена

Page 21: JavaScript. Loops and functions (in russian)

persons.some(): Boolean

Page 22: JavaScript. Loops and functions (in russian)

var isPensioners = false; // Слишком много шума и лишних слов for (var i = 0; i < persons.length; i++) { if (persons[i].age > 65) { isPensioners = true; break; } } console.log(isPensioners); // true // Лучше, чище, нагляднее var isPensioners = persons.some(function (person) { return person.age > 65; }); console.log(isPensioners); // true

some(): есть ли пенсионеры?

Page 23: JavaScript. Loops and functions (in russian)

persons.every(): Boolean

Page 24: JavaScript. Loops and functions (in russian)

var isAllAdults = true; // Слишком много шума и лишних слов for (var i = 0; i < persons.length; i++) { if (persons[i].age < 18) { isAllAdults = false; break; } } console.log(isAllAdults); // false // Лучше, чище, нагляднее var isAllAdults = persons.every(function (person) { return person.age >= 18; }); console.log(isAllAdults); // false

every(): все совершеннолетние?

Page 25: JavaScript. Loops and functions (in russian)

persons.filter(): Array

Page 26: JavaScript. Loops and functions (in russian)

var underages = []; // Слишком много шума и лишних слов for (var i = 0; i < persons.length; i++) { if (persons[i].age < 18) { underages.push(persons[i]); } } console.log(underages.length); // 1 // Лучше, чище, нагляднее var underages = persons.filter(function (person) { return person.age < 18; }); console.log(underages.length); // 1

filter(): список несовершеннолетних

Page 27: JavaScript. Loops and functions (in russian)

persons.reduce(): *

Page 28: JavaScript. Loops and functions (in russian)

var ageSumm = 0; // Слишком много шума и лишних слов for (var i = 0; i < persons.length; i++) { ageSumm += persons[i].age; } console.log(ageSumm / persons.length); // 20.5 // Лучше, чище, нагляднее var underages = persons.reduce(function (prev, current) { return prev + current.age; }, 0); // 0 - Аккумулятор console.log(ageSumm / persons.length); // 20.5

reduce(): средний возраст

Page 29: JavaScript. Loops and functions (in russian)

Цепочки вызовов persons.filter().map().join()

Page 30: JavaScript. Loops and functions (in russian)

var adultNames = persons // Сперва выбираем всех совершеннолетник .filter(function (person) { return person.age >= 18; }) // Затем оставляем только имена .map(function (person) { return person.name; }) // Склеиваем имена в строку .join(', '); console.log(adultNames + ' are adults'); // Ann, Peter are adults

Получить имена совершеннолетних

Page 31: JavaScript. Loops and functions (in russian)

Внимание все они не поддерживаются старыми браузерами!

5+ 3+ 10+ 3.2+ 9+

Page 32: JavaScript. Loops and functions (in russian)

Функции

Function Declaration,

Conditional Function Declaration,

Function Expression,

Named Function Expression,

IEFE

Page 33: JavaScript. Loops and functions (in russian)

33

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

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

Page 34: JavaScript. Loops and functions (in russian)

34

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

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

Function Declaration/Definition

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

Page 35: JavaScript. Loops and functions (in russian)

35

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

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

Conditional Function Declaration

Page 36: JavaScript. Loops and functions (in russian)

36

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

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

CFD+Strict Mode

Page 37: JavaScript. Loops and functions (in russian)

37

- Это 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 38: JavaScript. Loops and functions (in russian)

38

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

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

Named Function Expression

Page 39: JavaScript. Loops and functions (in russian)

39

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

function (){}(); // SyntaxError (function () { // OK var b = Math.sin(Math.PI / 3); alert(b * 2); }()); typeof b === "undefined";

IEFE – Замыкание, Модуль

Page 40: JavaScript. Loops and functions (in russian)

40

!function (){}(); // OK +function (){}(); // OK *function (){}(); // OK (function (){}()); // OK [function (){}()]; // OK var a = function (){}(); // Можно и так var a = (function (){}()); // Но лучше скобки оставлять

IEFE

Page 41: JavaScript. Loops and functions (in russian)

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

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

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

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

Лексическая

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

Page 42: JavaScript. Loops and functions (in russian)

42

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 43: JavaScript. Loops and functions (in russian)

43

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

GLOBAL a 1 foo func(on

foo c 2 bar func(on

bar e argument

Page 44: JavaScript. Loops and functions (in russian)

44

Вся эта цепочка остается в памяти, пока жива функция bar()

Page 45: JavaScript. Loops and functions (in russian)

45

// Замыкание var getMySecret = (function () { // Это значение нельзя изменить var mySecret = Math.sin(Math.PI / 3); return function () { return mySecret; }; }()); // Можем только получать getMySecret(); // 0.8660254037844386 typeof mySecret === "undefined";

Пример области видимости

Page 46: JavaScript. Loops and functions (in russian)

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

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

Прямой вызов

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

Вызов через new

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

Page 47: JavaScript. Loops and functions (in russian)

47

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

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

Page 48: JavaScript. Loops and functions (in russian)

48

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

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

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

Page 49: JavaScript. Loops and functions (in russian)

49

Это 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 50: JavaScript. Loops and functions (in russian)

50

Легко запомнить: что находится до "точки" является this

Page 51: JavaScript. Loops and functions (in russian)

51

Это 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 52: JavaScript. Loops and functions (in russian)

52

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

var a = function (a, b) { console.log(this, a, b); }; a.call([]); // [], undefined, 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 53: JavaScript. Loops and functions (in russian)

53

Это способ подменять 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 54: JavaScript. Loops and functions (in russian)

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

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

arguments

Page 55: JavaScript. Loops and functions (in russian)

55

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

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

Page 56: JavaScript. Loops and functions (in russian)

56

arguments

• Как и this появляется при вызове • Это не Array

–  нельзя forEach(), map(), filter() –  можно for () {}

• Содержит список всех аргументов –  arguments[0]… и .length

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

• Содержит ссылку на текущую функцию –  arguments.calle

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

Page 57: JavaScript. Loops and functions (in russian)

57

function myFunction(a) { console.log(arguments[0]); // 1 - ok a = 8; console.log(arguments[0]); // 8 - ??? } myFunction(1); function myFunctionStrict(a) { "use strict"; // <<< console.log(arguments[0]); // 1 - ok a = 8; console.log(arguments[0]); // 1 - ok } myFunctionStrict(1);

arguments и формальные параметры Без строгого режима arguments связан с формальными параметрами При добавлении "use strict" эта связь отменяется

Page 58: JavaScript. Loops and functions (in russian)

58

JavaScript Циклы и Функции •  for in

–  Итерирует перечисляемые свойства (собственные и прототипа) –  Используйте hasOwnProperty(name)

• Array.map().filter().reduce() • Function Expression • Function Declaration • Область видимости функции • Вызов функции и this

–  this зависит от способа вызова функции

• Аргументы и arguments –  arguments связан с формальными параметрами без StrictMode

Page 59: JavaScript. Loops and functions (in russian)

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

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

[email protected] azproduction

Спасибо