# ДЗ: Замыкания и Прототипное ООП. ## Мануалы - http://gitlab.a-level.com.ua/gitgod/BasicProgramming/src/master/08.md#---- - http://gitlab.a-level.com.ua/gitgod/FrontendLectures/src/master/Proto.md - https://learn.javascript.ru/prototypes ## Замыкания ### makeProfileTimer Напишите функцию `makeProfileTimer`, которая служит для замера времени выполнения другого кода и работает следующим образом: ```javascript var timer = makeProfileTimer() doSomething(); //некий код, время выполнения которого мы хотим измерить с высокой точностью alert(timer()); //alert должен вывести время в микросекундах от выполнения makeProfileTimer до момента вызова timer(), // т. е. измерить время выполнения doSomething ``` Используйте `performance.now()` ### makeSaver Напишите функцию `makeSaver`, которая: ```javascript var saver = makeSaver(Math.random) //создает функцию-хранилище результата переданной в качестве параметра функции (Math.random // в примере). На этом этапе Math.random НЕ вызывается var value1 = saver() //saver вызывает переданную в makeSaver функцию, запоминает результат и возвращает его var value2 = saver() //saver в дальнейшем просто хранит результат функции, и более НЕ вызывает переданную //в makeSaver функцию; value1 === value2 // всегда true ``` Таким образом `makeSaver` решает две задачи: 0. Навсегда сохраняет результат функции. Это актуально, например, для `Math.random`. 1. Действует *лениво*, то есть вызывает `Math.random` только тогда, когда результат *действительно* нужен. Если же по каким-то причинам значение не понадобится, то `Math.random` даже не будет вызван ### Final Countdown Напишите код, который будет делать обратный ежесекундный отсчёт в консоли, используя `console.log`. Используйте **Self Invoked Function** для создания замыкания и `setTimeout` для задержки вывода. Результатом должно быть: ```javascript 5 //пауза 1 секунда 4 //пауза 1 секунда 3 //пауза 1 секунда 2 //пауза 1 секунда 1 //пауза 1 секунда "поехали!" ``` ### myBind Изучите встроенную функцию `bind`, и сделайте свою версию, которая позволит определить "значение по умолчанию" не только для первых параметров, но для любых других, например для *степени* в Math.pow: ```javascript var pow5 = myBind(Math.pow, Math, [undefined, 5]) // первый параметр - функция для биндинга значений по умолчанию, // второй - this для этой функции, третий - массив, в котором undefined означает // параметры, которые должны передаваться при вызове, // а другие значения являются значениями по умолчанию: var cube = myBind(Math.pow, Math, [undefined, 3]) // cube возводит число в куб var chessMin = myBind(Math.min, Math, [undefined, 4, undefined, 5,undefined, 8,undefined, 9]) chessMin(-1,-5,3,15) // вызывает Math.min(-1, 4, -5, 5, 3, 8, 15, 9), результат -5 pow5(2) // => 32, вызывает Math.pow(2,5), соотнесите с [undefined, 5] cube(3) // => 27 var zeroPrompt = myBind(prompt, window, [undefined, "0"]) // аналогично, только теперь задается "0" как текст по умолчанию в prompt, // а текст приглашения пользователя задается при вызове zeroPrompt var someNumber = zeroPrompt("Введите число") // вызывает prompt("Введите число","0") ``` Массив, который идет третьим параметром определяет, какие поля должны подменяться значением по умолчанию, а какие - задаваться в последствии (`undefined`). ## Прототипное ООП ### `avg` Добавьте во все массивы метод `avg` (**average**, *средняя*), который будет рассчитывать среднее арифметическое для массива, используя прототип объекта `Array`. ```javascript [1,2,3].avg(); // => 2 [2,17,31,15,-15].avg(); // => 10 ``` ### `copy` Добавьте во все объекты метод `copy`, который будет копировать текущий объект. Используте прототип `Object`, и итерацию по ключам объекта. ```javascript var a = {year: 1999, month: 11}; var b = a.copy(); b.year = 2017; b // Object {year: 2017, month: 11} a // Object {year: 1999, month: 11} ``` ### `tags` Создайте иерархию объектов html-тэгов: - `Tag` - общий предок - `PairedTag` - наследник парный тэг. - `TagA` - тэг `A` и его основные параметры (`href` и текст ссылки, как минимум) - `TagDiv` - тэг `DIV`. - `UnpairedTag` - непарные тэги. - `TagBr` - `br` - `TagInput` - `input` и его параметры (`type`, `placeholder`, `value`, `name`) Выделите общие свойства и методы в предков (общие для всех тэгов - в `Tag`, общие для парных - в `PairedTag`, и т.п.). Каждый тэг должен иметь метод `getHTML`, возвращающая строку тэга. Установку параметров тэгов сделайте через геттеры и сеттеры. ```javascript var t = new Tag(); t.getHTML(); // => ""; var br = new TagBr(); br.getHTML(); // => "
" var i = new TagInput({'type': "text", placeholder: 'login', value: "", name: "login"}); i.getHTML(); // => " var google = new TagA(); google.setHref("http://google.com"); google.setText("гугл"); ``` ## ***пояса не обязательны к выполнению, содержaт опасные для мозга идеи*** ![лал](https://pp.vk.me/c637324/v637324002/23904/NAGaukM7hPY.jpg) ## Синий пояс Расширить задание `copy` глубоким рекурсивным копированием вложенных структур: ```javascript var a = [["aaaa"], {year: 1999, month: 11}]; var b = a.copy(); b[0].push(5); b // [["aaaa", 5], {year: 1999, month: 11}]; a // [["aaaa"], {year: 1999, month: 11}]; ```