hw_10_closures.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //======================================================
  2. // makeProfileTimer
  3. // Напишите функцию makeProfileTimer, которая служит для замера времени выполнения другого
  4. makeProfileTimer = function () {
  5. let t1 = performance.now();
  6. return function () {
  7. return performance.now() - t1;
  8. };
  9. };
  10. var timer = makeProfileTimer();
  11. alert("Замеряем время работы этого alert"); //некий код, время выполнения которого мы хотим измерить с высокой точностью
  12. alert(`Время работы кода составило ${timer()} милисекунд`);
  13. //======================================================
  14. //makeSaver
  15. // Напишите функцию makeSaver, которая:
  16. // var saver = makeSaver(Math.random) //создает функцию-хранилище результата переданной в качестве параметра функции (Math.random
  17. // // в примере). На этом этапе Math.random НЕ вызывается
  18. // var value1 = saver() //saver вызывает переданную в makeSaver функцию, запоминает результат и возвращает его
  19. // var value2 = saver() //saver в дальнейшем просто хранит результат функции, и более НЕ вызывает переданную
  20. // //в makeSaver функцию;
  21. // value1 === value2 // всегда true
  22. // var saver2 = makeSaver(() => console.log('saved function called') || [null, undefined, false, '', 0, Math.random()][Math.ceil(Math.random()*6)])
  23. // var value3 = saver2()
  24. // var value4 = saver2()
  25. // value3 === value4 // тоже должно быть true
  26. // Таким образом makeSaver решает две задачи:
  27. // Навсегда сохраняет результат функции. Это актуально, например, для Math.random.
  28. // Действует лениво, то есть вызывает Math.random только тогда, когда результат действительно нужен.
  29. // Если же по каким - то причинам значение не понадобится, то Math.random даже не будет вызван
  30. const makeSaver = function (func) {
  31. let isFirst = true;
  32. let result;
  33. return function () {
  34. if (isFirst) {
  35. result = func();
  36. console.log(`Запомнили: ${result}`);
  37. isFirst = false;
  38. }
  39. return result;
  40. };
  41. };
  42. var saver = makeSaver(Math.random);
  43. var value1 = saver();
  44. var value2 = saver();
  45. value1 === value2 ? alert(`value1 === value2 YAHOO!!!`) : alert(`value1 !== value2 :(`);
  46. var saver2 = makeSaver(
  47. () =>
  48. console.log("saved function called") ||
  49. [null, undefined, false, "", 0, Math.random()][Math.ceil(Math.random() * 6)]
  50. );
  51. var value3 = saver2();
  52. var value4 = saver2();
  53. value3 === value4 ? alert(`value3 === value4 YAHOO!!!`) : alert(`value3 !== value4 :(`);
  54. //======================================================
  55. // Final Countdown
  56. // Напишите код, который будет делать обратный ежесекундный отсчёт в консоли, используя console.log.
  57. // Используйте Self Invoked Function для создания замыкания и setTimeout для задержки вывода.
  58. //
  59. //
  60. // Not Self Invoked
  61. var finalCountdown = function (count) {
  62. setTimeout(() => console.log(count), 0);
  63. for (let i = count - 1; i > 0; i--) {
  64. setTimeout(() => console.log(count - i), i * 1000);
  65. }
  66. setTimeout(() => console.log("ПОЕХАЛИ!"), count * 1000);
  67. };
  68. finalCountdown(5);
  69. //
  70. //
  71. // Self Invoked !!! (не сразу, но сообразил как закрутить, чтобы не ждать в начале дополнительную секунду)
  72. var finalCountdown2 = function (count, i = 0) {
  73. if (!i) i = count;
  74. if (count < 0) {
  75. console.log("Все уже давно закончилось. Вы опоздали...");
  76. return;
  77. }
  78. let msg = !count ? "GO!" : count;
  79. if (count >= 0) {
  80. setTimeout(() => console.log(msg), 1000 * (i - count));
  81. finalCountdown2(count - 1, i);
  82. }
  83. return;
  84. };
  85. finalCountdown2(5);
  86. //======================================================
  87. // myBind
  88. // Изучите встроенную функцию bind, и сделайте свою версию,
  89. // которая позволит определить "значение по умолчанию" не только для первых параметров,
  90. // но для любых других, например для степени в Math.pow:
  91. // var pow5 = myBind(Math.pow, Math, [undefined, 5]) // первый параметр - функция для биндинга значений по умолчанию,
  92. // // второй - this для этой функции, третий - массив, в котором undefined означает
  93. // // параметры, которые должны передаваться при вызове,
  94. // // а другие значения являются значениями по умолчанию:
  95. // var cube = myBind(Math.pow, Math, [undefined, 3]) // cube возводит число в куб
  96. // pow5(2) // => 32, вызывает Math.pow(2,5), соотнесите с [undefined, 5]
  97. // cube(3) // => 27
  98. // var chessMin = myBind(Math.min, Math, [undefined, 4, undefined, 5,undefined, 8,undefined, 9])
  99. // chessMin(-1,-5,3,15) // вызывает Math.min(-1, 4, -5, 5, 3, 8, 15, 9), результат -5
  100. // var zeroPrompt = myBind(prompt, window, [undefined, "0"]) // аналогично, только теперь задается "0" как текст по умолчанию в prompt,
  101. // // а текст приглашения пользователя задается при вызове zeroPrompt
  102. // var someNumber = zeroPrompt("Введите число") // вызывает prompt("Введите число","0")
  103. function myBind(func, tempThis, tempArray) {
  104. return function (...arguments) {
  105. let i = 0;
  106. let newTempArray = tempArray.map((value) => (value === undefined ? arguments[i++] : value));
  107. return func.call(tempThis, ...newTempArray); // call || apply - вот в чем вопрос...
  108. };
  109. }
  110. function myBind_v2(func, tempThis, tempArray) {
  111. return function (...arguments) {
  112. let i = 0;
  113. let newTempArray = tempArray.map((value) => (value === undefined ? arguments[i++] : value));
  114. return func.apply(tempThis, newTempArray); // call || apply - вот в чем вопрос...
  115. };
  116. }
  117. var pow5 = myBind(Math.pow, Math, [undefined, 5]);
  118. var cube = myBind_v2(Math.pow, Math, [undefined, 3]);
  119. debugger;
  120. pow5(2); // => 32, вызывает Math.pow(2,5)
  121. cube(3); // 27
  122. var chessMin = myBind(Math.min, Math, [undefined, 4, undefined, 5, undefined, 8, undefined, 9]);
  123. chessMin(-1, -5, 3, 15); // вызывает Math.min(-1, 4, -5, 5, 3, 8, 15, 9), результат -5
  124. var zeroPrompt = myBind(prompt, window, [undefined, "0"]);
  125. var someNumber = zeroPrompt("Введите число"); // вызывает prompt("Введите число","0")