HW12.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Материал
  2. // Как и всегда, почитайте мануал, позапускайте примерчики, найдите ошибки, ощутите множественность Scope.
  3. {
  4. // done
  5. }
  6. // Предыдущие ДЗ
  7. // Изучите предыдущие несколько ДЗ и найдите где там применяются замыкания.Особенно это касается задач, связанных с DOM, да createPersonClosure не просто так имеет в названии слово "Closure".
  8. {
  9. // done
  10. }
  11. // makeProfileTimer
  12. // Напишите функцию makeProfileTimer, которая служит для замера времени выполнения другого кода и работает следующим образом:
  13. // Используйте performance.now()
  14. {
  15. function makeProfileTimer() {
  16. const start = performance.now()
  17. function endTime() {
  18. return performance.now() - start
  19. }
  20. return endTime
  21. }
  22. // проверка
  23. var timer = makeProfileTimer()
  24. alert('Замеряем время работы этого alert')
  25. alert(`Время выполнения кода: ${Math.round(timer())} мс`)
  26. }
  27. // makeSaver
  28. // Напишите функцию makeSaver, которая:
  29. // Таким образом makeSaver решает две задачи:
  30. // Навсегда сохраняет результат функции.Это актуально, например, для Math.random.
  31. // Действует лениво, то есть вызывает Math.random только тогда, когда результат действительно нужен.Если же по каким - то причинам значение не понадобится, то Math.random даже не будет вызван
  32. {
  33. function makeSaver(func) {
  34. const start = func()
  35. function saver() {
  36. return start
  37. }
  38. return saver
  39. }
  40. // Проверка раз
  41. var saver = makeSaver(Math.random) //создает функцию-хранилище результата переданной в качестве параметра функции (Math.random в примере). На этом этапе Math.random НЕ вызывается
  42. var value1 = saver() //saver вызывает переданную в makeSaver функцию, запоминает результат и возвращает его
  43. var value2 = saver() //saver в дальнейшем просто хранит результат функции, и более НЕ вызывает переданную в makeSaver функцию;
  44. value1 === value2 // всегда true
  45. var saver2 = makeSaver(() => console.log('saved function called') || [null, undefined, false, '', 0, Math.random()][Math.ceil(Math.random() * 6)])
  46. var value3 = saver2()
  47. var value4 = saver2()
  48. value3 === value4 // тоже должно быть true
  49. // Проверка два
  50. let namePrompt = prompt.bind(window, 'Как тебя зовут?')
  51. let nameSaver = makeSaver(namePrompt)
  52. alert(`Привет! Prompt еще не было!`)
  53. alert(`Привет ${nameSaver()}. Только что запустился prompt, первый и последний раз`)
  54. alert(`Слушай, ${nameSaver()}, го пить пиво. Ведь prompt был только один раз`)
  55. }
  56. // myBind
  57. // Изучите встроенную функцию bind, и сделайте свою версию, которая позволит определить "значение по умолчанию" не только для первых параметров, но для любых других, например для степени в Math.pow:
  58. // Массив, который идет третьим параметром определяет, какие поля должны подменяться значением по умолчанию, а какие - задаваться в последствии(undefined).
  59. {
  60. function myBind(func, zis, params) {
  61. function bind(...addParams) {
  62. let newParams = [...params]
  63. for (let i = 0; i < params.length; i++) {
  64. if (params[i] === undefined) {
  65. newParams[i] = addParams.shift()
  66. }
  67. }
  68. return func.bind(zis)(...newParams)
  69. }
  70. return bind
  71. }
  72. // Проверка
  73. var pow5 = myBind(Math.pow, Math, [, 5]) // первый параметр - функция для биндинга значений по умолчанию,
  74. // второй - this для этой функции, третий - массив, в котором undefined означает параметры, которые должны передаваться при вызове,
  75. // а другие значения являются значениями по умолчанию:
  76. var cube = myBind(Math.pow, Math, [, 3]) // cube возводит число в куб
  77. pow5(2) // => 32, вызывает Math.pow(2,5), соотнесите с [undefined, 5]
  78. cube(3) // => 27
  79. var chessMin = myBind(Math.min, Math, [, 4, , 5, , 8, , 9])
  80. chessMin(-1, -5, 3, 15) // вызывает Math.min(-1, 4, -5, 5, 3, 8, 15, 9), результат -5
  81. var zeroPrompt = myBind(prompt, window, [undefined, "0"]) // аналогично, только теперь задается "0" как текст по умолчанию в prompt,
  82. // а текст приглашения пользователя задается при вызове zeroPrompt
  83. var someNumber = zeroPrompt("Введите число") // вызывает prompt("Введите число","0")
  84. const bindedJoiner = myBind((...params) => params.join(''), null, [, 'b', , , 'e', 'f'])//('a','c','d') === 'abcdef'
  85. bindedJoiner('a', 'c', 'd') === 'abcdef'
  86. bindedJoiner('1', '2', '3') === '1b23ef'
  87. }
  88. // checkResult
  89. // Напишите декоратор checkResult, который:
  90. // принимает функцию для запуска и проверки результата(оригинал)
  91. // принимает функцию для проверки результата(валидатор)
  92. // возвращает обертку, которая запускает оригинал до тех пор, пока оригинал не вернет значение, удовлетворяющее функции - валидатору.В валидатор передается результат оригинальной функции.Если валидатор возвращает true, то обертка возвращает результат оригинальной функции.Если валидатор возвращает что - то другое, то оригинал запускается еще, пока валидатор не вернет true.
  93. // Используя checkResult сделайте функции, которые:
  94. // randomHigh.Возвращает случайное число в диапазоне от 0.5 до 1
  95. // alwaysSayYes.Достает пользователя окном confirm пока он не согласится(не нажмет OK)
  96. // respectMe.Достает пользователя запуском этой фунцкии, пока какое - то из полей не введено
  97. {
  98. function checkResult(original, validator) {
  99. function wrapper(...params) {
  100. let res = original(...params)
  101. do {
  102. res = original.apply(this, params)
  103. } while (!(validator(res)))
  104. return res
  105. }
  106. return wrapper
  107. }
  108. // Проверка
  109. //numberPrompt - это функция, которая будет запускать prompt до тех пор, пока пользователь не введет число
  110. //параметры передаются насквозь в оригинал. Не забудьте передать this, используя call или apply
  111. const numberPrompt = checkResult(prompt, x => !isNaN(+x))
  112. let number = +numberPrompt("Введите число", "0")
  113. //gamePrompt - это функция, которая будет запускать prompt до тех пор, пока пользователь не введет одно из слов 'камень', 'ножницы', 'бумага'
  114. const gamePrompt = checkResult(prompt, x => ['камень', 'ножницы', 'бумага'].includes(x.toLowerCase()))
  115. const turn = gamePrompt("Введите что то из списка: 'камень', 'ножницы', 'бумага'")
  116. // randomHigh.Возвращает случайное число в диапазоне от 0.5 до 1
  117. const randomHigh = checkResult(Math.random, x => x >= 0.5 && x <= 1 ? true : false)
  118. console.log(randomHigh())
  119. // alwaysSayYes.Достает пользователя окном confirm пока он не согласится(не нажмет OK)
  120. const alwaysSayYes = checkResult(confirm, x => x)
  121. alwaysSayYes()
  122. // respectMe.Достает пользователя запуском этой фунцкии, пока какое - то из полей не введено
  123. // НО ПРОБЕМА - из-за коряво написанной функции enterPersonData невозможно понять, работает ли проверка, из-за того, что в enterPersonData невозможно нажать отправить пустую строку или отказаться от ввода данных - сразу ломается trim
  124. const enterPersonData = () => {
  125. const arr = {}
  126. const name = (prompt('Ввеедиет Ваше Имя в поле ниже')).trim()
  127. arr.name = `${name[0].toUpperCase()}${name.slice(1).toLowerCase()}`
  128. const surname = (prompt('Ввеедиет Вашу Фамилию в поле ниже')).trim()
  129. arr.surname = `${surname[0].toUpperCase()}${surname.slice(1).toLowerCase()}`
  130. const fatherName = (prompt('Ввеедиет Ваше Отчество в поле ниже')).trim()
  131. arr.fatherName = `${fatherName[0].toUpperCase()}${fatherName.slice(1).toLowerCase()}`
  132. const fullName = `${name[0].toUpperCase()}${name.slice(1).toLowerCase()} ${surname[0].toUpperCase()}${surname.slice(1).toLowerCase()} ${fatherName[0].toUpperCase()}${fatherName.slice(1).toLowerCase()}`
  133. arr.fullName = fullName
  134. return arr
  135. }
  136. function verification(arr) {
  137. console.log(arr.name)
  138. if (arr.name) return true
  139. if (arr.surname) return false
  140. if (arr.fatherName) return false
  141. return false
  142. }
  143. const respectMe = checkResult(enterPersonData, verification)
  144. respectMe()
  145. }