javascript Базовый. Занятие 03

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

Upload: igor-shkulipa

Post on 21-Mar-2017

106 views

Category:

Education


0 download

TRANSCRIPT

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

Темы лекции: Функции.

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

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

Занятие 3

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

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

Функция (Википедия) — фрагмент программного кода(подпрограмма), к которому можно обратиться из другого местапрограммы.

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

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

После выполнения функции управление возвращается обратно вадрес возврата — точку программы, где данная функция была вызвана.

Функция

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

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

function f1(){

alert ("I'm function declaration!");

}

f1(); // Вызов функции

Function Declaration

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

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

var f2 = function (){

alert ("I'm function expression!");

}

f2();

Function Expression

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

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

Функция может содержать локальные переменные, объявленныечерез var. Такие переменные видны только внутри функции:

function showMessage() {

var message = "Hi";

alert(message);

}

showMessage();

alert(message);

Блоки if/else, switch, for, while, do..while не влияют на область видимости переменных. При объявлении переменной в таких блоках,

она всё равно будет видна во всей функции.

Локальные переменные

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

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

Функция может обратиться ко внешней переменной, например:

var userName = "User";

function showMessage() {

var message = "Hi, " + userName;

alert(message);

}

showMessage();

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

Глобальные (внешние) переменные

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

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

var message ="Hello!";

function showMessage() {

var message = "Hi";

alert(message);

};

showMessage();

alert(message);

Глобальные и локальные переменные

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

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

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

1. alert(a); var a = 5;

2. for (i=0; i<5; i++) { } var i;

3. var i = 10;

for (var i=0; i < 20; i++) { }

var i = 5;

“Поднятие” переменных

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

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

var a = "Outer a";

var b = "Outer b";

var c = "Outer c";

function f(a) {

var b = "Inner b";

var c = "Inner c";

var d = "Inner d";

alert(a);

alert(b);

alert(c);

alert(d);

}

f("Any a");

alert(a);

alert(b);

alert(c);

alert(d);

Lexical Environment

f.LexicalEnv.a === undefined;

f.LexicalEnv.b === "Inner b"

f.LexicalEnv.c === "Inner c"

f.LexicalEnv.d === "Inner d"

f.[[Scope]] === window

f.[[Scope]].a === "Outer a"

f.[[Scope]].b === "Outer b"

f.[[Scope]].c === "Outer c"

f.[[Scope]].c === undefined

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

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

Lexical Environment

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

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

• Значение функции возвращается оператором return

• Вызов return прекращает функцию вне зависимости от того,следуют ли за ним еще операторы.

• Если return; вызван без значения, или функция завершилась безreturn, то её результат равен undefined.

Возврат значения

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

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

function hello(name, surname) {

alert("Hello, " + name + " " + surname);

name = name || "Name";

surname = surname || "Surname";

}

hello();

hello("Ivan");

hello("Iavn", "Ivanov");

Параметры функций

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

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

function hello(name, surname) {

name = name || "Name";

surname = surname || "Surname";

alert("Hello, " + name + " " + surname);

}

hello();

hello("Ivan");

hello("Iavn", "Ivanov");

Параметры функций

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

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

function sum() {

var s = 0;

for (var i = 0; i < arguments.length; i++) {

s += arguments[i];

}

return s;

}

alert(sum(1,2,3,4));

arguments

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

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

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

• Это псевдомассив, то есть объект, который похож на массив, в нёместь нумерованные свойства и length, но методов массива унего нет.

arguments – это псевдомассив

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

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

f3();

var f3 = function (){

alert ("I'm function expression!");

}

Function Expression

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

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

Function Expression

f3();

var f3 = function (){

alert ("I'm function expression!");

}

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

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

f4;

var f4 = function (){

alert ("I'm function expression!");

}

Function Expression

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

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

f4;

var f4 = function (){

alert ("I'm function expression!");

}

Function Expression

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

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

var b=true;

var f5 = function f6() {

alert("Function");

if (b) {

b = false;

f5();

f6();

}

}

f5();

f6();

Именованные Function Expression

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

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

Именованные Function Expression

var b=true;

var f5 = function f6() {

alert("Function");

if (b) {

b = false;

f5();

f6();

}

}

f5();

f6();

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

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

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

(function() {})();

function() { }();

function doSomething() { }();

+function() { }();

!function() { }();

var sum = function(a,b) {

return a+b; }(2,2);

Just-in-time функции

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

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

Объектами первого класса (англ. first-class object, first-class entity, first-class citizen) в контексте конкретного языка программированияназываются элементы, которые могут быть переданы как параметр,возвращены из функции, присвоены переменной

function sum() {

var s = 0;

for (var i = 0; i < arguments.length; i++) {

s += arguments[i];

}

return s;

}

alert(sum);

Функция - объект первого класса

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

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

function sum() {

var s = 0;

for (var i = 0; i < arguments.length; i++) {

s += arguments[i];

}

return s;

}

function show(f) {

alert(f(1,2,3,4));

}

show(sum);

Функция - объект первого класса

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

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

function a() {

alert(“function”);

alert(a.hello);

}

a.hello = “Hello”;

a();

Свойства функций

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

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

var sub = new Function("a, b", "return a-b");

var sum = new Function("", " var s = 0; \

for (var i = 0; i < arguments.length; i++) { \

s += arguments[i]; \

} \

return s; \

");

alert(sub(1,2) );

alert(sum(1,2,3,4) );

new Function

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

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

function outer() {

function inner() {

return "inner";

}

return inner();

}

alert(outer());

alert(inner());

Вложенные функции

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

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

Каждый вызов функции включает в себя и область видимости,и переменную this, и контекст выполнения.

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

Значение переменной this — это ссылка на объект, который«вызывает» код в данный момент.

Контекст выполнения содержит и область видимости, иаргументы функции, и переменную this.

Контекстом еще часто называют просто значение переменнойthis внутри функции.

По умолчанию this – это глобальный объект, то есть window.

function f1() {};

f1(); // this == ???

var obj = {};

obj.f2 = function () {};

obj.f2(); // this == ???

Контекст выполнения

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

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

Функция call может применяться для вызова функции в контекстенужного объекта.

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

function getName() {

return this.name;

}

var persone = {name: "Ivan"};

alert(getName.call(persone));

Задание контекста вручную. call

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

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

function sayHi(message) {

return message + ", " + this.name;

}

var persone = {name: "Ivan"};

alert(sayHi.call(persone, "Hello"));

Задание контекста вручную. call

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

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

Метод apply очень похож на call, за исключением передачиаргументов. В apply используется массив аргументов вместо спискаименованных параметров.

function sayHi(message1, message2) {

return message1 + " and " + message2 + ", " + this.name;

}

var persone = {name: "Ivan"};

alert(sayHi.apply(persone, ["Hello", "Hi"]));

Задание контекста вручную. apply

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

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

var numbers = [1, 5, 2, 4, 8, -1, 1, 3];

alert(Math.max.apply( null, numbers ));

Задание контекста вручную. apply

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

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

В JavaScript для привязки функций есть метод bind. Он поддерживаетсябольшинством современных браузеров, за исключением IE<9.

Этот метод позволяет привязать функцию к нужному контексту и даже каргументам.

var wrapper = func.bind(context[, arg1, arg2...]);

• func - произвольная функция

• wrapper - функция-обёртка, которую возвращает вызов bind. Она вызываетfunc, фиксируя контекст и, если указаны, первые аргументы.

• context - обертка wrapper будет вызывать функцию с контекстом this = context.

• arg1, arg2, … - если указаны аргументы arg1, arg2... — они будут прибавлены ккаждому вызову новой функции, причем станут перед теми, которые указаныпри вызове.

bind

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

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

Пример bind

function sayHi(message) {

return message + ", " + this.name;

}

var persone = {name: "Ivan"};

var sayHello= sayHi.bind(persone, "Hello");

var sayHelloNull= sayHi.bind(null, "Hello");

alert(sayHello());

alert(sayHelloNull());

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

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

bind с аргументами

bind может создавать обёртку, которая фиксирует не только контекст,но и ряд аргументов.

function sum(a,b){

return a+b;

}

var addOne=sum.bind(null, 1);

var addTwo=sum.bind(null, 2);

var addTen=sum.bind(null, 10);

alert(addOne(10));

alert(addTwo(10));

alert(addTen(10));

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

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

Функция eval позволяет выполнить код, переданный ей в видестроки. Этот код будет выполнен в текущей области видимости.

eval (" function sum() { \

var s = 0; \

for (var i = 0; i < arguments.length; i++) { \

s += arguments[i]; \

} \

return s; \

}\

\

function show(f) { \

alert(f(1,2,3,4)); \

} \

\

show(sum); \

");

Запуск кода из строки: eval

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

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

function makeCounter() {

var count = 0;

return function() {

return count++;

}

}

var counter=makeCounter();

alert(counter());

alert(counter());

alert(counter());

Замыкания

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

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

Замыкание — это особенный вид объекта, который сочетает двевещи: функцию и окружение, в котором функция была создана. Окружениесостоит из любой локальной переменной, которая была в области действияфункции во время создания замыкания. В этом случае, helloIvan— этозамыкание, которое содержит и функцию alertHi, и строку “Ivan”, которыесуществовали во время создания замыкания.

function sayHi() {

var name = "Ivan";

function alertHi() {

alert("Hello, " + name);

}

return alertHi;

}

var helloIvan = sayHi();

helloIvan ();

Замыкания

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

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

Wikipedia:Каррирование или карринг (англ. currying) в информатике —

преобразование функции от многих аргументов в функцию, берущую свои аргументы поодному. Это преобразование было введено М. Шейнфинкелем и Г. Фреге и получилосвое название в честь Х. Карри.

Для функции h типа h : (A × B) → C оператор каррирования Λ выполняетпреобразование Λ(h) : A → (B → C). Таким образом, Λ(h) берет аргумент типа A ивозвращает функцию типа B → C. С интуитивной точки зрения, каррирование функциипозволяет фиксировать ее некоторый аргумент, возвращая функцию от остальныхаргументов. Таким образом, Λ представляет собой функцию типа Λ : (A × B → C) → (A →

(B → C)).

function sayHi(message) {

return function (name) {

alert(message + ", " + name);

}

}

sayHi("Hello")("Ivan");

Каррирование

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

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

«Модуль» — это популярная реализация паттерна,инкапсулирующего приватную информацию, состояние и структуру,используя замыкания. Это позволяет оборачивать публичные и приватныеметоды и переменные в модули, и предотвращать их попадание вглобальный контекст, где они могут конфликтовать с интерфейсами другихразработчиков. Паттерн «модуль» возвращает только публичную часть API,оставляя всё остальное доступным только внутри замыканий.

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

;var module = (function (window, document) {

function sayHi(message) {

return function (name) {

alert(message + ", " + name);

}

}

sayHi("Hello")("Module");

})(window, document);

Паттерн «Модуль»