$30 off During Our Annual Pro Sale. View Details »

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

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

Mikhail Davydov

October 23, 2012
Tweet

More Decks by Mikhail Davydov

Other Decks in Education

Transcript

  1. for in •  Можно итерировать поля объекта •  Пробегает по

    перечисляемым свойствам –  По собственным свойствам –  И по свойствам прототипа •  Перечисляемость – скрытое свойство
  2. 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: Пример
  3. 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: Пример с загрязнением
  4. 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
  5. var persons = [{ "name": "Ann", "age": 21 }, {

    "name": "Helen", "age": 16 }, { "name": "Peter", "age": 76 }, { "name": "Jack", "age": 12 }]; Пример
  6. // Слишком много шума и лишних слов 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 букву имени
  7. 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(): получить только имена
  8. 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(): есть ли пенсионеры?
  9. 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(): все совершеннолетние?
  10. 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(): список несовершеннолетних
  11. 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(): средний возраст
  12. 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 Получить имена совершеннолетних
  13. 33 На самом деле Function в JavaScript – это Object

    со скрытым полем [[Call]] http://es5.github.com/#x13.2
  14. 34 - Это Statement - Инициализируется во время входа в

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

    в контекст или в рантайме - По стандарту такая запись недопустима if (true) { function a() { return 1; } } else { function a() { return 2; } } a(); // Firefox – 1, Others - 2 Conditional Function Declaration
  16. 36 - При использовании строгого режима возникнет ошибка SyntaxError "use

    strict"; if (true) { function a() { return 1; } } else { function a() { return 2; } } // SyntaxError // Function Expression! CFD+Strict Mode
  17. 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
  18. 38 - Это тот же Function Expression - Можно обратиться

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

    понять интерпретатору, что этот код - Function Expression -  IEFE позволяет эмулировать блочную область видимости function (){}(); // SyntaxError (function () { // OK var b = Math.sin(Math.PI / 3); alert(b * 2); }()); typeof b === "undefined"; IEFE – Замыкание, Модуль
  20. 40 !function (){}(); // OK +function (){}(); // OK *function

    (){}(); // OK (function (){}()); // OK [function (){}()]; // OK var a = function (){}(); // Можно и так var a = (function (){}()); // Но лучше скобки оставлять IEFE
  21. Область видимости Определяется во время создания функции Не меняется при

    передаче функции Образует цепочку областей видимости Лексическая Образует «замыкание»
  22. 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
  23. 45 // Замыкание var getMySecret = (function () { //

    Это значение нельзя изменить var mySecret = Math.sin(Math.PI / 3); return function () { return mySecret; }; }()); // Можем только получать getMySecret(); // 0.8660254037844386 typeof mySecret === "undefined"; Пример области видимости
  24. Вызов функции и this this – основная грабля в JavaScript

    Прямой вызов Вызов через c оператором точка и [] Вызов через new Вызов через call, apply, bind
  25. 48 () – это оператор вызова функции this всегда undefined

    но он трансформируется в global В строгом режиме всегда undefined (трансформации нет) function a() { console.log(this); } a(); // window (undefined -> window) function b() { "use strict"; console.log(this); } b(); // undefined Прямой вызов – через оператор ()
  26. 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
  27. 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
  28. 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
  29. 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
  30. 55 Передача значения в функцию •  Значения передаются по ссылке

    •  Можно менять «поля» переданного объекта •  Примитив менять нельзя •  Можно переписать ссылку без потери объекта
  31. 56 arguments •  Как и this появляется при вызове • 

    Это не Array –  нельзя forEach(), map(), filter() –  можно for () {} •  Содержит список всех аргументов –  arguments[0]… и .length •  Содержит ссылку на вызывающую функцию –  arguments.caller –  Deprecated! •  Содержит ссылку на текущую функцию –  arguments.calle http://es5.github.com/#x10.6
  32. 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" эта связь отменяется
  33. 58 JavaScript Циклы и Функции •  for in –  Итерирует

    перечисляемые свойства (собственные и прототипа) –  Используйте hasOwnProperty(name) •  Array.map().filter().reduce() •  Function Expression •  Function Declaration •  Область видимости функции •  Вызов функции и this –  this зависит от способа вызова функции •  Аргументы и arguments –  arguments связан с формальными параметрами без StrictMode