index.js 12 KB

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