ClosureProtoHW.md 7.8 KB

ДЗ: Замыкания и Прототипное ООП.

Мануалы

Замыкания

makeProfileTimer

Напишите функцию makeProfileTimer, которая служит для замера времени выполнения другого кода и работает следующим образом:

   var timer = makeProfileTimer()
   doSomething();  //некий код, время выполнения которого мы хотим измерить с высокой точностью
   alert(timer()); //alert должен вывести время в микросекундах от выполнения makeProfileTimer до момента вызова timer(), 
                   // т. е. измерить время выполнения doSomething

Используйте performance.now()

makeSaver

Напишите функцию makeSaver, которая:

    var saver = makeSaver(Math.random) //создает функцию-хранилище результата переданной в качестве параметра функции (Math.random 
                                      // в примере). На этом этапе Math.random НЕ вызывается
    var value1 = saver()              //saver вызывает переданную в makeSaver функцию, запоминает результат и возвращает его
    var value2 = saver()              //saver в дальнейшем просто хранит результат функции, и более НЕ вызывает переданную 
                                      //в makeSaver функцию;
    value1 === value2                 // всегда true

Таким образом makeSaver решает две задачи:

  1. Навсегда сохраняет результат функции. Это актуально, например, для Math.random.
  2. Действует лениво, то есть вызывает Math.random только тогда, когда результат действительно нужен. Если же по каким-то причинам значение не понадобится, то Math.random даже не будет вызван

Final Countdown

Напишите код, который будет делать обратный ежесекундный отсчёт в консоли, используя console.log. Используйте Self Invoked Function для создания замыкания и setTimeout для задержки вывода. Результатом должно быть:

   5 //пауза 1 секунда
   4 //пауза 1 секунда
   3 //пауза 1 секунда
   2 //пауза 1 секунда
   1 //пауза 1 секунда
   "поехали!"

myBind

Изучите встроенную функцию bind, и сделайте свою версию, которая позволит определить "значение по умолчанию" не только для первых параметров, но для любых других, например для степени в Math.pow:

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.

[1,2,3].avg(); // => 2
[2,17,31,15,-15].avg(); // => 10

copy

Добавьте во все объекты метод copy, который будет копировать текущий объект. Используте прототип Object, и итерацию по ключам объекта.

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, возвращающая строку тэга. Установку параметров тэгов сделайте через геттеры и сеттеры.

var t = new Tag();
t.getHTML(); // => "";

var br = new TagBr();
br.getHTML(); // => "<br />"

var i = new TagInput({'type': "text", placeholder: 'login', value: "", name: "login"});
i.getHTML(); // => "<input type='text' placeholder='login' value='' name='login'>

var google = new TagA();
google.setHref("http://google.com");
google.setText("гугл");

пояса не обязательны к выполнению, содержaт опасные для мозга идеи

лал

Синий пояс

Расширить задание copy глубоким рекурсивным копированием вложенных структур:

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}];