4. Statement
• Блочное выражение
– if (){}, try{}catch(e){}, function a(){}
• Директива интерпретатору
– return, throw, break, continue, var, …
• Может включать другие блочные выражения
• Может включать выражения
• Не возвращает значение
• Не может быть аргументом Expression
• Можно сделать из Expression – Expression;
4
http://es5.github.com/#x12
5. Expression
• Оператор
– С одним аргументом typeof, !, (), ++, --, new, +,…
– С двумя ==, ===, >, <, instanceof, +, -,…
– С тремя a?b:c,…
– Вызов функции
– Оператор запятая
• Может включать другие операторы
• Не может включать Statement
• Возвращает значение
• Может быть в составе Statement
5
http://es5.github.com/#x11
7. Приведение типов
• Зависит от оператора
– Оператор имеет определенный алгоритм
• Зависит от типа аргументов и мест
• Внутренние функции JavaScript
– ToNumber, ToString, ToBoolean, ToObject
7
8. Пример: оператор + и примитивы
Сильно перегружен: сложение чисел, конкатенация строк
“2” + 3; // “23”
2 + 3; // 5
// Что происходит в внутренностях JavaScript:
if (Type(“2”) === “String” || Type(3) === “String”) {
return Concat(ToString(“2”), ToString(3));
} else {
return ToNumber(2) + ToNumber(3);
}
8 http://es5.github.com/#x11.6.1
13. Оператор typeof
Алгоритм
- Ссылка не достижима (IsUnresolvableReference) – возвращаем "undefined"
- Иначе смотрим по таблице
Type(val) Результат
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Object (нативный и не имеет [[Call]]) "object"
Object (нативный или не нативный и "function”
имеет [[Call]])
Object (не нативный и не имеет [[Call]]) Не "undefined", "boolean",
"number", "string"
13 http://es5.github.com/#x11.4.3
16. Функции
Function Declaration,
Conditional Function Declaration,
Function Expression,
Named Function Expression,
IEFE
17. На самом деле Function в
JavaScript – это Object со
скрытым полем [[Call]]
17 http://es5.github.com/#x13.2
18. Function Declaration/Definition
- Это Statement
- Инициализируется во время входа в контекст
- Объявляется в блоке функции или в глобальном блоке
a(); // OK
function a() {
b(); // OK
function b() {
}
}
a();
18
http://es5.github.com/#x13
19. Conditional Function Declaration
- Это тоже Statement
- Инициализируется во время входа в контекст или в рантайме
- По стандарту такая запись недопустима
if (true) {
function a() {
return 1;
}
} else {
function a() {
return 2;
}
}
a(); // Firefox – 1, Others - 2
19
20. CFD+Strict Mode
- При использовании строгого режима возникнет ошибка SyntaxError
"use strict";
if (true) {
function a() {
return 1;
}
} else {
function a() {
return 2;
}
}
// SyntaxError
// Function Expression!
20
21. Function Expression
- Это expression
- Инициализируется в рантайме
- Объявляется где угодно
a(); // error
var a = function () {
b(); // error
var b = function () {
};
b(); // ok
};
a(); // ok
21
http://es5.github.com/#x11.2.5
22. Named Function Expression
- Это тот же Function Expression
- Можно обратиться к себе по своему имени
- Имя доступно только в своем блоке (кроме старых IE)
(function timer() {
setTimeout(timer, 1000);
console.log(+new Date);
}());
typeof timer; // undefined, Old IE - function
22
23. IEFE
- Это тот же 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
23
24. Область видимости
Определяется во время создания функции
Не меняется при передаче функции
Образует цепочку областей видимости
Лексическая
Образует «замыкание»
25. Область видимости
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
25 http://es5.github.com/#x10.2
27. Вызов функции и this
this – основная грабля в JavaScript
Прямой вызов
Вызов через c оператором точка и []
Вызов через new
Вызов через call, apply, bind
28. This в JavaScript
определяется во время
вызова функции!
28 http://es5.github.com/#x11.2.3
29. Прямой вызов – через оператор ()
() – это оператор вызова функции
this всегда undefined но он трансформируется в global
В строгом режиме всегда undefined (трансформации нет)
function a() {
console.log(this);
}
a(); // window (undefined -> window)
function b() {
“use strict”;
console.log(this);
}
b(); // undefined
29
30. Оператор . и []
Это 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(); // ???
30 http://es5.github.com/#x11.2.1
31. Оператор new
Это Expression
new – это еще один способ вызова функции
Каждая функция может быть конструктором
this – пустой объект со ссылкой на prototype вызываемой функции
var A = function () {
console.log(this);
console.log(this.__proto__ === A.prototype);
};
new A(); // Object, true
31 http://es5.github.com/#x11.2.2
32. Call, apply
Это способ управлять значением 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
http://es5.github.com/#x15.3.4.4
32 http://es5.github.com/#x15.3.4.3
33. Bind
Это способ подменять this без вызова функции
this – объект, который вы передаете
var a = function () {
console.log(this);
};
var b = a.bind({});
b(); // {}
http://es5.github.com/#x15.3.4.5
33 MDN Function#bind http://clck.ru/2EeTx
35. Передача значения в функцию
• Значения передаются по ссылке
• Можно менять «поля» переданного объекта
• Примитив менять нельзя
• Можно переписать ссылку без потери
объекта
35
36. arguments
• Как и this появляется при вызове
• Это не Array
• Содержит список всех аргументов
– arguments[0]…
• Содержит ссылку на вызывающий конекст
– arguments.caller
– Deprecated!
• Содержит ссылку на себя
– arguments.calle
36 http://es5.github.com/#x10.6
38. prototype и __proto__
• prototype – свойство функции
– Оно есть у функции с рождения
– По умолчанию это пустой объект
• __proto__ – ссылка на prototype у объекта
– Во многих движках JavaScript оно скрыто
– Определяется во время работы оператора new
http://es5.github.com/#x15.3.5.2
38
http://es5.github.com/#x8.6.2
40. Цепочка прототипов
foo
b 146
__proto__ object
Foo.prototype
bar function
a 123
__proto__ object
Object.prototype
__proto__ null
40
http://es5.github.com/#x4.2.1
41. Оператор . и []
• Выполняет поиск свойства
• Использует цепочку прототипов
• Ищет в собственных свойствах
• Затем рекурсивно по ссылке __proto__
• Если __proto__ null – возвратит undefined
41 http://es5.github.com/#x11.2.1
42. Оператор instanceof
var Foo = function () {
this.b = 146;
};
var foo = new Foo();
foo instanceof Foo; // true
foo instanceof Object; // true <- Магия??
foo instanceof Array; // false
42 http://es5.github.com/#x11.8.6
46. Strict Mode
На самоподготовку
- выделите отличия от обычного режима
- всегда ли стоит применять Strict Mode?
- в каком месте кода стоит объявлять SM?
http://es5.github.com/#x10.1.1