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