Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ШРИ - JavaScript базовые знания

ШРИ - JavaScript базовые знания

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

Video https://events.yandex.ru/lib/talks/704/

Mikhail Davydov

October 11, 2012
Tweet

More Decks by Mikhail Davydov

Other Decks in Education

Transcript

  1. View Slide

  2. Михаил Давыдов
    Разработчик JavaScript
    JavaScript
    Базовые знания

    View Slide

  3. Базовый синтаксис
    Expression (Выражение, Оператор),
    Statement (Блочное выражение, Блок)

    View Slide

  4. 4
    Statement
    •  Блочное выражение
    –  if (){}, try{}catch(e){}, function a(){}
    •  Директива интерпретатору
    –  return, throw, break, continue, var, …
    •  Может включать другие блочные выражения
    •  Может включать выражения
    •  Не возвращает значение
    •  Не может быть аргументом Expression
    •  Можно сделать из Expression – Expression;
    http://es5.github.com/#x12

    View Slide

  5. 5
    Expression
    •  Оператор
    –  С одним аргументом typeof, !, (), ++, --, new, +,…
    –  С двумя ==, ===, >, –  С тремя a?b:c,…
    –  Вызов функции
    –  Оператор запятая
    •  Может включать другие операторы
    •  Не может включать Statement
    •  Возвращает значение
    •  Может быть в составе Statement
    http://es5.github.com/#x11

    View Slide

  6. Приведение типов

    View Slide

  7. 7
    Приведение типов
    •  Зависит от оператора
    –  Оператор имеет определенный алгоритм
    •  Зависит от типа аргументов и мест
    •  Внутренние функции JavaScript
    –  ToNumber, ToString, ToBoolean, ToObject

    View Slide

  8. 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);
    }
    http://es5.github.com/#x11.6.1

    View Slide

  9. 9
    Что если один из операндов
    – Object?

    View Slide

  10. 10
    Применяется тот же алгоритм
    Вся «магия» в ToString({})
    “2” + {}; // ”2[object Object]”
    Пример: оператор + объект
    if (IsCallable({}.toString)) {
    return ({}).toString();
    } else if (IsCallable({}.valueOf)) {
    return ({}). valueOf();
    } else {
    throw new TypeError();
    }
    Concat(ToString(“2”), ToString({}));
    ToString({}) -> ToPrimitive({}, “String”)
    ToPrimitive({}, “String”) -> ({}).[[DefaultValue]](“String”)
    http://es5.github.com/#x8.12.8

    View Slide

  11. 11
    На самоподготовку [] + {};

    View Slide

  12. 12
    The Abstract Equality Comparison Algorithm
    http://es5.github.com/#x11.9.3
    '' === '0' // false!
    0 === '' // false!
    0 === '0' // false!
    false === undefined // false!
    false === null // false!
    null === undefined // false!
    +0 === -0 // true!
    Операторы == и ===
    '' == '0' // false
    0 == '' // true
    0 == '0' // true
    false == undefined // false
    false == null // false
    null == undefined // true
    The Strict Equality Comparison Algorithm
    http://es5.github.com/#x11.9.6

    View Slide

  13. 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"
    - Иначе смотрим по таблице

    View Slide

  14. 14
    WAT?
    •  [1] > 0; // ?
    •  [1,1] > 0; // ?
    •  [1,] > 0; // ?
    •  [1,,] > 0; // ?
    •  [1] > "0"; // ?

    View Slide

  15. 15
    WAT?
    •  [1] > 0; // true
    •  [1,1] > 0; // false
    •  [1,] > 0; // true
    •  [1,,] > 0; // false
    •  [1] > "0"; // ?

    View Slide

  16. Функции
    Function Declaration,
    Conditional Function Declaration,
    Function Expression,
    Named Function Expression,
    IEFE

    View Slide

  17. 17
    На самом деле Function в
    JavaScript – это Object со
    скрытым полем [[Call]]
    http://es5.github.com/#x13.2

    View Slide

  18. 18
    - Это Statement
    - Инициализируется во время входа в контекст
    - Объявляется в блоке функции или в глобальном блоке
    a(); // OK
    function a() {
    b(); // OK
    function b() {
    }
    }
    a();
    Function Declaration/Definition
    http://es5.github.com/#x13

    View Slide

  19. 19
    - Это тоже Statement
    - Инициализируется во время входа в контекст или в рантайме
    - По стандарту такая запись недопустима
    if (true) {
    function a() {
    return 1;
    }
    } else {
    function a() {
    return 2;
    }
    }
    a(); // Firefox – 1, Others - 2
    Conditional Function Declaration

    View Slide

  20. 20
    - При использовании строгого режима возникнет ошибка SyntaxError
    "use strict";
    if (true) {
    function a() {
    return 1;
    }
    } else {
    function a() {
    return 2;
    }
    }
    // SyntaxError
    // Function Expression!
    CFD+Strict Mode

    View Slide

  21. 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

    View Slide

  22. 22
    - Это тот же Function Expression
    - Можно обратиться к себе по своему имени
    - Имя доступно только в своем блоке (кроме старых IE)
    (function timer() {
    setTimeout(timer, 1000);
    console.log(+new Date);
    }());
    typeof timer; // undefined, Old IE - function
    Named Function Expression

    View Slide

  23. 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

    View Slide

  24. Область видимости
    Определяется во время создания функции
    Не меняется при передаче функции
    Образует цепочку областей видимости
    Лексическая
    Образует «замыкание»

    View Slide

  25. 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

    View Slide

  26. 26
    Цепочка областей видимости
    GLOBAL
    a 1
    foo func(on
    foo
    c 2
    bar func(on
    bar
    e argument

    View Slide

  27. Вызов функции и this
    this – основная грабля в JavaScript
    Прямой вызов
    Вызов через c оператором точка и []
    Вызов через new
    Вызов через call, apply, bind

    View Slide

  28. 28
    This в JavaScript
    определяется во время
    вызова функции!
    http://es5.github.com/#x11.2.3

    View Slide

  29. 29
    () – это оператор вызова функции
    this всегда undefined но он трансформируется в global
    В строгом режиме всегда undefined (трансформации нет)
    function a() {
    console.log(this);
    }
    a(); // window (undefined -> window)
    function b() {
    “use strict”;
    console.log(this);
    }
    b(); // undefined
    Прямой вызов – через оператор ()

    View Slide

  30. 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

    View Slide

  31. 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

    View Slide

  32. 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

    http://es5.github.com/#x15.3.4.3

    View Slide

  33. 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

    View Slide

  34. Вызов функции: arguments
    Передача значения
    arguments

    View Slide

  35. 35
    Передача значения в функцию
    •  Значения передаются по ссылке
    •  Можно менять «поля» переданного объекта
    •  Примитив менять нельзя
    •  Можно переписать ссылку без потери
    объекта

    View Slide

  36. 36
    arguments
    •  Как и this появляется при вызове
    •  Это не Array
    •  Содержит список всех аргументов
    –  arguments[0]…
    •  Содержит ссылку на вызывающий конекст
    –  arguments.caller
    –  Deprecated!
    •  Содержит ссылку на себя
    –  arguments.calle
    http://es5.github.com/#x10.6

    View Slide

  37. Прототипное наследование
    prototype и __proto__,
    Цепочка прототипов,
    Оператор instanceof

    View Slide

  38. 38
    prototype и __proto__
    •  prototype – свойство функции
    –  Оно есть у функции с рождения
    –  По умолчанию это пустой объект
    •  __proto__ – ссылка на prototype у объекта
    –  Во многих движках JavaScript оно скрыто
    –  Определяется во время работы оператора new
    http://es5.github.com/#x15.3.5.2
    http://es5.github.com/#x8.6.2

    View Slide

  39. 39
    var Foo = function () {
    this.b = 146; // Собственное свойство
    };
    Foo.prototype.bar = function () {
    console.log(this);
    };
    Foo.prototype.a = 123;
    var foo = new Foo();
    foo.bar(); // foo
    foo.a; // 123
    foo['b']; // 146
    foo.c; // undefined
    Foo.prototype.c = 8;
    foo.c; // 8 Цепочка прототипов

    View Slide

  40. 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

    View Slide

  41. 41
    Оператор . и []
    •  Выполняет поиск свойства
    •  Использует цепочку прототипов
    •  Ищет в собственных свойствах
    •  Затем рекурсивно по ссылке __proto__
    •  Если __proto__ null – возвратит undefined
    http://es5.github.com/#x11.2.1

    View Slide

  42. 42
    var Foo = function () {
    this.b = 146;
    };
    var foo = new Foo();
    foo instanceof Foo; // true
    foo instanceof Object; // true foo instanceof Array; // false
    Оператор instanceof
    http://es5.github.com/#x11.8.6

    View Slide

  43. 43
    Оператор instanceof
    •  Использует цепочку прототипов
    •  Рекурсивно ищет __proto__ === prototype

    View Slide

  44. 44
    Цепочка прототипов
    foo
    b 146
    __proto__ object
    Foo.prototype
    bar function
    a 123
    __proto__ object
    Object.prototype
    __proto__ null

    View Slide

  45. Оператор new
    На самоподготовку
    - Напишите функцию эмулирующую оператор
    new
    http://es5.github.com/#x11.2.2

    View Slide

  46. Strict Mode
    На самоподготовку
    - выделите отличия от обычного режима
    - всегда ли стоит применять Strict Mode?
    - в каком месте кода стоит объявлять SM?
    http://es5.github.com/#x10.1.1

    View Slide

  47. Annotated ECMAScript 5.1
    http://es5.github.com/

    View Slide

  48. Mozilla Developer Network
    https://developer.mozilla.org/en-US/

    View Slide

  49. Основы и заблуждения насчет JavaScript
    http://habrahabr.ru/post/120193/

    View Slide

  50. Михаил Давыдов
    Разработчик JavaScript
    [email protected]
    azproduction
    Спасибо

    View Slide