//Замыкания //makeProfileTimer let makeProfileTimer = function() { let profileTimerNowStart = performance.now(); return function() { let profileTimerNowEnd = performance.now(); return `Алерт работал ${profileTimerNowEnd - profileTimerNowStart} микросекунд`; } } var timer = makeProfileTimer() alert('Замеряем время работы этого alert'); //некий код, время выполнения которого мы хотим измерить с высокой точностью alert(timer()); //alert должен вывести время в микросекундах от выполнения makeProfileTimer до момента вызова timer(), // т. е. измерить время выполнения alert //makeSaver let makeSaver = function(f) { let count = 0; //Переменная которая будет проверять запускали ли ранее функцию, если запускали то будет возвращено старое значение let functionStorage; //Тут я буду хранить результат работы переданной функции let saverFunction = function() { if(count == 0) { //Проверка была ли функция запущена ранее functionStorage = f(); //Если count == 0 то функцию ранее не запускали, тут я сохраняю результат переданной функции } else { return functionStorage; //Усли функция ранее запускалась то я возвращаю старое значение } count++; //После первого запуска функции счетчик будет увеличиваться return functionStorage; } return saverFunction; } var saver = makeSaver(Math.random) //создает функцию-хранилище результата переданной в качестве параметра функции (Math.random // в примере). На этом этапе Math.random НЕ вызывается var value1 = saver() //saver вызывает переданную в makeSaver функцию, запоминает результат и возвращает его var value2 = saver() //saver в дальнейшем просто хранит результат функции, и более НЕ вызывает переданную //в makeSaver функцию; console.log(value1 === value2); // всегда true 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() console.log(value3 === value4); // тоже должно быть true let namePrompt = prompt.bind(window, 'Как тебя зовут?') let nameSaver = makeSaver(namePrompt) alert(`Привет! Prompt еще не было!`) alert(`Привет ${nameSaver()}. Только что запустился prompt, первый и последний раз`) alert(`Слушай, ${nameSaver()}, го пить пиво. Ведь prompt был только один раз`) //Final Countdown let count = 1; for(let i = 5; i > 0; i--) { let countdown = function() { console.log(i); if(i == 1) { console.log("Поехали"); } } setTimeout(countdown, function(){ return 1000 * count++; }()); } //myBind let myBind = function(bindFunction, thisForFunction, arr) { //Не нашел применения второму параметру ) let newArr = []; // В этом массиве я буду хранить значения которые должны передаваться при вызове и значения по умолчанию let index = 0; // Каунер который я буду в дальнейшем использовать что бы корректно заменять undefined на данные которые передаются при вызове let myBindFunction = function(...customArr) { for(let item of arr) { //Цикл который проходит массив данных по умолчанию if(item == undefined) { //В массиве данных по умолчанию проверяю элемент на undefined, если true то меняю его на элемент который был передан при вызове newArr.push(customArr[index]); index++; } else { newArr.push(item); } } return bindFunction(...newArr); } return myBindFunction; } var pow5 = myBind(Math.pow, Math, [undefined, 5]) // первый параметр - функция для биндинга значений по умолчанию, // второй - this для этой функции, третий - массив, в котором undefined означает // параметры, которые должны передаваться при вызове, // а другие значения являются значениями по умолчанию: var cube = myBind(Math.pow, Math, [undefined, 3]) // cube возводит число в куб pow5(2) // => 32, вызывает Math.pow(2,5), соотнесите с [undefined, 5] cube(3) // => 27 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 var zeroPrompt = myBind(prompt, window, [undefined, "0"]) // аналогично, только теперь задается "0" как текст по умолчанию в prompt, // а текст приглашения пользователя задается при вызове zeroPrompt var someNumber = zeroPrompt("Введите число") // вызывает prompt("Введите число","0") myBind((...params) => params.join(''), null, [undefined, 'b', undefined, undefined, 'e', 'f'])('a','c','d') === 'abcdef'