4. for, while, do while –
работают так же как и во
всех языках. Ура!
5. for in
• Можно итерировать поля объекта
• Пробегает по перечисляемым свойствам
– По собственным свойствам
– И по свойствам прототипа
• Перечисляемость – скрытое свойство
6. 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: Пример
20. 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(): получить только имена
22. 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(): есть ли пенсионеры?
26. 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(): список несовершеннолетних
30. 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
Получить имена совершеннолетних
31. Внимание все они не
поддерживаются старыми
браузерами!
5+ 3+ 10+ 3.2+ 9+
33. 33
На самом деле Function в
JavaScript – это Object со
скрытым полем [[Call]]
http://es5.github.com/#x13.2
34. 34
- Это Statement
- Инициализируется во время входа в контекст
- Объявляется в блоке функции или в глобальном блоке
a(); // OK
function a() {
b(); // OK
function b() {
}
}
a();
Function Declaration/Definition
http://es5.github.com/#x13
35. 35
- Это тоже Statement
- Инициализируется во время входа в контекст или в рантайме
- По стандарту такая запись недопустима
if (true) {
function a() {
return 1;
}
} else {
function a() {
return 2;
}
}
a(); // Firefox – 1, Others - 2
Conditional Function Declaration
36. 36
- При использовании строгого режима возникнет ошибка SyntaxError
"use strict";
if (true) {
function a() {
return 1;
}
} else {
function a() {
return 2;
}
}
// SyntaxError
// Function Expression!
CFD+Strict Mode
37. 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
38. 38
- Это тот же Function Expression
- Можно обратиться к себе по своему имени
- Имя доступно только в своем блоке (кроме старых IE)
(function timer() {
setTimeout(timer, 1000);
console.log(+new Date);
}());
typeof timer; // undefined, Old IE - function
Named Function Expression
39. 39
- Это тот же Function Expression
- Мы даем понять интерпретатору, что этот код - Function Expression
- IEFE позволяет эмулировать блочную область видимости
function (){}(); // SyntaxError
(function () { // OK
var b = Math.sin(Math.PI / 3);
alert(b * 2);
}());
typeof b === "undefined";
IEFE – Замыкание, Модуль
40. 40
!function (){}(); // OK
+function (){}(); // OK
*function (){}(); // OK
(function (){}()); // OK
[function (){}()]; // OK
var a = function (){}(); // Можно и так
var a = (function (){}()); // Но лучше скобки оставлять
IEFE
41. Область видимости
Определяется во время создания функции
Не меняется при передаче функции
Образует цепочку областей видимости
Лексическая
Образует «замыкание»
42. 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
45. 45
// Замыкание
var getMySecret = (function () {
// Это значение нельзя изменить
var mySecret = Math.sin(Math.PI / 3);
return function () {
return mySecret;
};
}());
// Можем только получать
getMySecret(); // 0.8660254037844386
typeof mySecret === "undefined";
Пример области видимости
46. Вызов функции и this
this – основная грабля в JavaScript
Прямой вызов
Вызов через c оператором точка и []
Вызов через new
Вызов через call, apply, bind
48. 48
() – это оператор вызова функции
this всегда undefined но он трансформируется в global
В строгом режиме всегда undefined (трансформации нет)
function a() {
console.log(this);
}
a(); // window (undefined -> window)
function b() {
"use strict";
console.log(this);
}
b(); // undefined
Прямой вызов – через оператор ()
49. 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
51. 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
52. 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
53. 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
55. 55
Передача значения в функцию
• Значения передаются по ссылке
• Можно менять «поля» переданного объекта
• Примитив менять нельзя
• Можно переписать ссылку без потери
объекта
56. 56
arguments
• Как и this появляется при вызове
• Это не Array
– нельзя forEach(), map(), filter()
– можно for () {}
• Содержит список всех аргументов
– arguments[0]… и .length
• Содержит ссылку на вызывающую функцию
– arguments.caller
– Deprecated!
• Содержит ссылку на текущую функцию
– arguments.calle
http://es5.github.com/#x10.6
57. 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" эта связь отменяется
58. 58
JavaScript Циклы и Функции
• for in
– Итерирует перечисляемые свойства (собственные и прототипа)
– Используйте hasOwnProperty(name)
• Array.map().filter().reduce()
• Function Expression
• Function Declaration
• Область видимости функции
• Вызов функции и this
– this зависит от способа вызова функции
• Аргументы и arguments
– arguments связан с формальными параметрами без StrictMode