КРиПИ - JavaScript Циклы и Функции

КРиПИ - JavaScript Циклы и Функции

B827d6cfdfbcfce33700b0e6cc03e344?s=128

Mikhail Davydov

October 23, 2012
Tweet

Transcript

  1. None
  2. Михаил Давыдов Разработчик JavaScript JavaScript Циклы и Функции

  3. Циклы – Statements for, while, do while, for in

  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: Пример
  7. 7 hasOwnProperty и toString и др. – не перечисляемые свойства

  8. 8 // А что если? Object.prototype.toString = function () {};

  9. 9 Если toString и другие переписать, то они станут уже

    перечисляемыми
  10. 10 var Constructor = function () {}; Constructor.prototype.myValue = 123;

    var obj = new Constructor(); obj.a = 1; obj.b = {}; obj.c = 'ololo'; for (var keyName in obj) { console.log(keyName + ': ' + obj[keyName]); } // Результат "a: 1" "b: [object Object]" "c: 'ololo'" "myValue: 123" // <<< ???? for in: Пример с загрязнением
  11. 11 myValue – перечисляемое, но не собственное свойство

  12. 12 var Constructor = function () {}; Constructor.prototype.myValue = 123;

    var obj = new Constructor(); obj.a = 1; obj.b = {}; obj.c = 'ololo'; for (var keyName in obj) { if (obj.hasOwnProperty(keyName)) { console.log(keyName + ': ' + obj[keyName]); } } // Результат "a: 1" "b: [object Object]" "c: 'ololo'" for in: Пример c hasOwnProperty
  13. Циклы Expressions forEach map every, some filter reduce, reduceRight

  14. Как правило все циклы связаны с массивом

  15. Почему бы тогда не добавить итераторов к Array?!

  16. var persons = [{ "name": "Ann", "age": 21 }, {

    "name": "Helen", "age": 16 }, { "name": "Peter", "age": 76 }, { "name": "Jack", "age": 12 }]; Пример
  17. persons.forEach(): Undefined

  18. // Слишком много шума и лишних слов for (var i

    = 0; i < persons.length; i++) { console.log(persons[i].name[0]); } // "A", "H", "P", "J" // Лучше, чище, нагляднее persons.forEach(function (person) { console.log(person.name[0]); }); // "A", "H", "P", "J" forEach(): вывести 1 букву имени
  19. persons.map(): Array

  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(): получить только имена
  21. persons.some(): Boolean

  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(): есть ли пенсионеры?
  23. persons.every(): Boolean

  24. var isAllAdults = true; // Слишком много шума и лишних

    слов for (var i = 0; i < persons.length; i++) { if (persons[i].age < 18) { isAllAdults = false; break; } } console.log(isAllAdults); // false // Лучше, чище, нагляднее var isAllAdults = persons.every(function (person) { return person.age >= 18; }); console.log(isAllAdults); // false every(): все совершеннолетние?
  25. persons.filter(): Array

  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(): список несовершеннолетних
  27. persons.reduce(): *

  28. var ageSumm = 0; // Слишком много шума и лишних

    слов for (var i = 0; i < persons.length; i++) { ageSumm += persons[i].age; } console.log(ageSumm / persons.length); // 20.5 // Лучше, чище, нагляднее var underages = persons.reduce(function (prev, current) { return prev + current.age; }, 0); // 0 - Аккумулятор console.log(ageSumm / persons.length); // 20.5 reduce(): средний возраст
  29. Цепочки вызовов persons.filter().map().join()

  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+
  32. Функции Function Declaration, Conditional Function Declaration, Function Expression, Named Function

    Expression, IEFE
  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
  43. 43 Цепочка областей видимости GLOBAL a 1 foo func(on foo

    c 2 bar func(on bar e argument
  44. 44 Вся эта цепочка остается в памяти, пока жива функция

    bar()
  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
  47. 47 This в JavaScript определяется во время вызова функции! http://es5.github.com/#x11.2.3

  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
  50. 50 Легко запомнить: что находится до "точки" является this

  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
  54. Вызов функции: arguments Передача значения arguments

  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
  59. Михаил Давыдов Разработчик JavaScript azproduction@yandex-team.ru azproduction Спасибо