Курс по уеб програмиране (2014), занятие №3 - JavaScript (част 1/2)
JavaScript Базовый. Занятие 03.
-
Upload
igor-shkulipa -
Category
Education
-
view
95 -
download
0
Transcript of JavaScript Базовый. Занятие 03.
Темы лекции: Функции.
Тренер: Игорь Шкулипа, к.т.н.
JavaScript. Базовый курс
Занятие 3
http://www.slideshare.net/IgorShkulipa 2http://www.slideshare.net/IgorShkulipa 2
Функция (Википедия) — фрагмент программного кода(подпрограмма), к которому можно обратиться из другого местапрограммы.
В большинстве случаев с функцией связывается идентификатор,но многие языки допускают и безымянные функции.
С именем функции неразрывно связан адрес первой инструкции(оператора), входящей в функцию, которой передаётся управление приобращении к функции.
После выполнения функции управление возвращается обратно вадрес возврата — точку программы, где данная функция была вызвана.
Функция
http://www.slideshare.net/IgorShkulipa 3http://www.slideshare.net/IgorShkulipa 3
function f1(){
alert ("I'm function declaration!");
}
f1(); // Вызов функции
Function Declaration
http://www.slideshare.net/IgorShkulipa 4http://www.slideshare.net/IgorShkulipa 4
var f2 = function (){
alert ("I'm function expression!");
}
f2();
Function Expression
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 не влияют на область видимости переменных. При объявлении переменной в таких блоках,
она всё равно будет видна во всей функции.
Локальные переменные
http://www.slideshare.net/IgorShkulipa 6http://www.slideshare.net/IgorShkulipa 6
Функция может обратиться ко внешней переменной, например:
var userName = "User";
function showMessage() {
var message = "Hi, " + userName;
alert(message);
}
showMessage();
Доступ возможен не только на чтение, но и на запись. Приэтом, так как переменная внешняя, то изменения будут видны иснаружи функции.
Глобальные (внешние) переменные
http://www.slideshare.net/IgorShkulipa 7http://www.slideshare.net/IgorShkulipa 7
var message ="Hello!";
function showMessage() {
var message = "Hi";
alert(message);
};
showMessage();
alert(message);
Глобальные и локальные переменные
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;
“Поднятие” переменных
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
http://www.slideshare.net/IgorShkulipa 10http://www.slideshare.net/IgorShkulipa 10
Lexical Environment
http://www.slideshare.net/IgorShkulipa 11http://www.slideshare.net/IgorShkulipa 11
• Значение функции возвращается оператором return
• Вызов return прекращает функцию вне зависимости от того,следуют ли за ним еще операторы.
• Если return; вызван без значения, или функция завершилась безreturn, то её результат равен undefined.
Возврат значения
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");
Параметры функций
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");
Параметры функций
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
http://www.slideshare.net/IgorShkulipa 15http://www.slideshare.net/IgorShkulipa 15
• Полный список аргументов, с которыми вызвана функция, доступенчерез arguments.
• Это псевдомассив, то есть объект, который похож на массив, в нёместь нумерованные свойства и length, но методов массива унего нет.
arguments – это псевдомассив
http://www.slideshare.net/IgorShkulipa 16http://www.slideshare.net/IgorShkulipa 16
f3();
var f3 = function (){
alert ("I'm function expression!");
}
Function Expression
http://www.slideshare.net/IgorShkulipa 17http://www.slideshare.net/IgorShkulipa 17
Function Expression
f3();
var f3 = function (){
alert ("I'm function expression!");
}
http://www.slideshare.net/IgorShkulipa 18http://www.slideshare.net/IgorShkulipa 18
f4;
var f4 = function (){
alert ("I'm function expression!");
}
Function Expression
http://www.slideshare.net/IgorShkulipa 19http://www.slideshare.net/IgorShkulipa 19
f4;
var f4 = function (){
alert ("I'm function expression!");
}
Function Expression
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
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();
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 функции
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);
Функция - объект первого класса
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);
Функция - объект первого класса
http://www.slideshare.net/IgorShkulipa 25http://www.slideshare.net/IgorShkulipa 25
function a() {
alert(“function”);
alert(a.hello);
}
a.hello = “Hello”;
a();
Свойства функций
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
http://www.slideshare.net/IgorShkulipa 27http://www.slideshare.net/IgorShkulipa 27
function outer() {
function inner() {
return "inner";
}
return inner();
}
alert(outer());
alert(inner());
Вложенные функции
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 == ???
Контекст выполнения
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
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
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
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
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
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());
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));
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
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());
Замыкания
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 ();
Замыкания
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");
Каррирование
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);
Паттерн «Модуль»