// makeProfileTimer // Напишите функцию makeProfileTimer, которая служит для замера времени выполнения другого кода и работает // следующим образом: Используйте performance.now() make_profile_timer: { function makeProfileTimer() { let t0 = performance.now(); return function () { let t1 = performance.now(); return t1 - t0; } } var timer = makeProfileTimer(); alert('Замеряем время работы этого alert'); //некий код, время выполнения которого мы хотим измерить с высокой точностью alert(timer()); //alert должен вывести время в микросекундах от выполнения makeProfileTimer до момента вызова timer(), // т. е. измерить время выполнения alert } // makeSaver // Напишите функцию makeSaver, которая: //создает функцию-хранилище результата переданной в качестве параметра функции (Math.random в примере). На // этом этапе Math.random НЕ вызывается saver вызывает переданную в makeSaver функцию, запоминает результат // и возвращает его saver в дальнейшем просто хранит результат функции, и более НЕ вызывает переданную //в makeSaver функцию; make_saver: { function makeSaver(fn) { let result; let resultSaved = false; return function () { if (!resultSaved) { result = fn(); resultSaved = true; } return result; } } var saver = makeSaver(Math.random); var value1 = saver(); var value2 = saver(); value1 === value2; var saver2 = makeSaver(() => console.log('saved function called') || [null, undefined, false, '', 0, Math.random()][Math.ceil(Math.random() * 6)]); var value3 = saver2(); var value4 = saver2(); value3 === value4; let namePrompt = prompt.bind(window, 'Как тебя зовут?'); let nameSaver = makeSaver(namePrompt); alert(`Привет! Prompt еще не было!`); alert(`Привет ${nameSaver()}. Только что запустился prompt, первый и последний раз`); alert(`Слушай, ${nameSaver()}, го пить пиво. Ведь prompt был только один раз`); } // myBind // Изучите встроенную функцию bind, и сделайте свою версию, которая позволит определить "значение по умолчанию" // не только для первых параметров, но для любых других, например для степени в Math.pow: // Массив, который идет третьим параметром определяет, какие поля должны подменяться значением по умолчанию, а // какие - задаваться в последствии (undefined). my_bind: { function myBind(fn, context, defaultParams) { return function (...enteredParams) { let params = [...defaultParams]; for (let i = 0; i < defaultParams.length; i++) { if (defaultParams[i] === undefined) { params[i] = enteredParams.shift(); } }; return fn.bind(context)(...params); } } var pow5 = myBind(Math.pow, Math, [, 5]); var cube = myBind(Math.pow, Math, [, 3]); console.log(pow5(2)); console.log(cube(3)); var chessMin = myBind(Math.min, Math, [, 4, , 5, , 8, , 9]); console.log(chessMin(-1, -5, 3, 15)); var zeroPrompt = myBind(prompt, window, [undefined, "0"]); var someNumber = zeroPrompt("Введите число"); console.log(someNumber); const bindedJoiner = myBind((...params) => params.join(''), null, [, 'b', , , 'e', 'f']); console.log(bindedJoiner('a', 'c', 'd') === 'abcdef'); console.log(bindedJoiner('1', '2', '3') === '1b23ef'); } // checkResult // Напишите декоратор checkResult, который: // принимает функцию для запуска и проверки результата (оригинал) // принимает функцию для проверки результата (валидатор) // возвращает обертку, которая запускает оригинал до тех пор, пока оригинал не вернет значение, удовлетворяющее // функции-валидатору. В валидатор передается результат оригинальной функции. Если валидатор возвращает true, // то обертка возвращает результат оригинальной функции. Если валидатор возвращает что-то другое, то оригинал // запускается еще, пока валидатор не вернет true. // Используя checkResult сделайте функции, которые: // randomHigh. Возвращает случайное число в диапазоне от 0.5 до 1 // alwaysSayYes. Достает пользователя окном confirm пока он не согласится (не нажмет OK) // respectMe. Достает пользователя запуском этой фунцкии, пока какое-то из полей не введено check_result: { function checkResult(original, validator) { function wrapper(...params) { let result; do { result = original.apply(this, params); } while (!validator(result)); return result; } return wrapper; } const numberPrompt = checkResult(prompt, x => !isNaN(+x)); let number = +numberPrompt("Введите число", "0"); console.log(number); const gamePrompt = checkResult(prompt, x => ['камень', 'ножницы', 'бумага'].includes(x.toLowerCase())); const turn = gamePrompt("Введите что то из списка: 'камень', 'ножницы', 'бумага'"); console.log(turn); const randomHigh = checkResult(Math.random, x => x >= 0.5 && x <= 1 ? true : false) const alwaysSayYes = checkResult(confirm, x => x) }