问题:
构建一个addTwo函数,作用为接受一个参数并将参数加2。
题解:
1 2 3 4 5 6 7 8 |
// Challenge 1 const addTwo = (num) => { return num + 2; }; // To check if you've completed this function, uncomment these console.logs! console.log(addTwo(3)); console.log(addTwo(10)); |
挑战2 addS
问题:
构建一个addS函数,作用为接受一个参数并将参数与“s”拼接。
题解:
1 2 3 4 5 6 7 8 |
// Challenge 2 const addS = (word) => { return word.toString() + 's'; }; // Uncomment these to check your work console.log(addS('pizza')); console.log(addS('bagel')); |
挑战3 map
问题:
构建一个map函数,其接受两个参数:
- 数值型数组
- 回调函数——一个应用于上述数值型数组中的每一个元素的函数(于map函数内)
map函数的返回值为包含上述数值型数组元素逐个运行回调函数后生成的元素值的新数组。
1 2 3 |
map([1,2,3,4,5], multiplyByTwo); //-> [2,4,6,8,10] multiplyByTwo(1); //-> 2 multiplyByTwo(2); //-> 4 |
题解:
1 2 3 4 5 6 7 8 9 10 |
// Challenge 3 const map = (array, callback) => { const newArray = []; for(let i = 0; i< array.length; i++){ newArray.push(callback(array[i])); } return newArray; }; console.log(map([1, 2, 3], addTwo)); |
挑战4 forEach
问题:
函数forEach接受一个数组和一个回调函数,运行回调函数于输入数组的每一个元素。forEach函数无返回值。
1 2 3 4 |
let alphabet = ''; const letters = ['a', 'b', 'c', 'd']; forEach(letters, char => alphabet += char); console.log(alphabet); //prints 'abcd' |
题解:
1 2 3 4 5 6 7 8 9 10 11 12 |
// Challenge 4 const forEach = (array, callback) => { for(let i = 0; i<array.length; i++){ callback(array[i]); } }; // See for yourself if your forEach works! let alphabet = ''; const letters = ['a', 'b', 'c', 'd']; forEach(letters, char => alphabet += char); console.log(alphabet); //prints 'abcd' |
挑战5 mapWith
问题:
在这个挑战中,你需要将map函数重构为mapWith。这一次你要在mapWith中使用forEach函数而不是使用for循环。
题解:
1 2 3 4 5 6 7 |
// Challenge 5 const mapWith = (array, callback) => { const newArray = newArray; forEach(array, el => newArray.push(callback(el))); return newArray; }; console.log(mapWith([1, 2, 3], addTwo)); |
挑战6 reduce
问题:
函数reduce接受一个数组并将数组内的所有值合并为一个值。比如,它可以将数组求和,求积,以及其它你想加进函数中的操作。
1 2 3 |
const nums = [4, 1, 3]; const add = (a, b) => a + b; reduce(nums, add, 0); //-> 8 |
以下是它的运行原理。函数有一个“累加器值”(第三个参数),作用为充当初始值并且累加每一次循环的输出值。数组参数会被遍历,传递“累加器值“和新的数组元素值作为参数到回调函数中。回调函数的返回值会成为新的”累加器值“。下一个循环会使用这个新”累加器值“。在上面的例子中,”累加器值“刚开始为0,调用add(0, 4),”累加器值“变为4,然后add(4, 1)将其变为5,最后add(5, 3)得到8并最终返回。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 |
// Challenge 6 const reduce = (array, callback, initialValue) => { let newValue = initialValue; for(let i = 0; i<array.length; i++){ newValue = callback(newValue, array[i]); } return newValue; }; const nums = [4, 1, 3]; const add = (a, b) => a + b; console.log(reduce(nums, add, 0)); //-> 8 |
挑战7 intersection
问题:
构建intersection函数,作用为比较输入进来的多组数组并返回一个包含数组间共同元素的新数组。奖励:使用reduce!
题解:
1 2 3 4 5 6 7 8 9 |
// Challenge 7 const intersection = (arrays) => { return arrays.reduce((acc, curr) => { return curr.filter(el => acc.includes(el)); }) }; console.log(intersection([[5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]])); // should log: [5, 15] |
挑战8 union
问题:
构建union函数,作用为比较输入进来的多组数组并返回一个包含输入数组中所有元素的新数组。如果存在重复元素,则新数组中仅保留一个,另外需保留新数组的元素顺序为从第一个输入数组的第一个元素开始。奖励:使用reduce!
题解:
1 2 3 4 5 6 7 8 9 10 |
// Challenge 8 const union = (arrays) => { return arrays.reduce((acc, curr) => { // acc.push(curr.filter(el => !acc.includes(el))); return acc.concat(curr.filter(el => !acc.includes(el))); }) }; console.log(union([[5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]])); // should log: [5, 10, 15, 88, 1, 7, 100] |
挑战9 objOfMatches
问题:
构建objOfMatches函数,接受两个数组和一个回调函数作为参数,作用为创建一个特定对象并返回。objOfMatches会使用回调函数测试第一个数组的每一个元素以确认其输出是否匹配于第二个数组内相同下标的元素。如果匹配,第一个数组内的这个元素会成为所创建对象的键,而第二个数组内的相同下标元素则会成为对应的值。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Challenge 9 const objOfMatches = (array1, array2, callback) => { const matchObj = {}; for(let i =0; i<array1.length; i++){ if(callback(array1[i])===array2[i]){ matchObj[array1[i]] = array2[i]; } } return matchObj; }; console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], (str) => str.toUpperCase())); // should log: { hi: 'HI', bye: 'BYE', later: 'LATER' } |
挑战10 multiMap
问题:
构建multiMap函数,接受两个数组作为参数,第一个数组的元素为值而第二个数组的元素为回调函数。multiMap会返回一个特定对象,该对象的键为第一个数组的值,键对应的值则是将键依序传入第二个数组的回调函数中得到的返回值组成的新数组。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Challenge 10 const multiMap = (arrVals, arrCallbacks) => { const multiMapObj = {}; let tempArray = []; arrVals.forEach(el => { tempArray = []; for(let i=0; i<arrCallbacks.length; i++){ tempArray.push(arrCallbacks[i](el)); } multiMapObj[el] = tempArray; }) return multiMapObj; }; console.log(multiMap(['catfood', 'glue', 'beer'], [(str) => str.toUpperCase(), (str) => str[0].toUpperCase() + str.slice(1).toLowerCase(), (str) => str + str])); // should log: { catfood: ['CATFOOD', 'Catfood', 'catfoodcatfood'], glue: ['GLUE', 'Glue', 'glueglue'], beer: ['BEER', 'Beer', 'beerbeer'] } |
挑战11 commutative
问题:
构建commutative函数,接受参数为两个回调函数和一个值。commutative会返回一个布尔值,从而表明运行第一个回调函数于输入值,再将得到的返回值输入到第二个回调函数中运行,得到的结果与逆序操作是否相同(即运行输入值于第二个回调函数,得到的返回值再输入到第一个回调函数中)。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Challenge 11 const commutative = (func1, func2, value) => { if(func1(func2(value)) === func2(func1(value))){ returntrue; } else { returnfalse; } }; /*** Uncomment these to check your work! ***/ const multBy3 = n => n * 3; const divBy4 = n => n / 4; const subtract5 = n => n - 5; console.log(commutative(multBy3, divBy4, 11)); // should log: true console.log(commutative(multBy3, subtract5, 10)); // should log: false console.log(commutative(divBy4, subtract5, 48)); // should log: false |
挑战12 objectFilter
问题:
构建objectFilter函数,第一个参数为对象,第二个参数为回调函数。objectFilter函数会返回特定对象。此特定对象所包含的属性为输入对象中值与其对应键传入回调函数得到的返回值一致的键值对。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Challenge 12 const objFilter = (obj, callback) => { const objectFilterObj = {}; for(let key in obj) { if(obj[key] === callback(key)){ objectFilterObj[key] = obj[key]; } } return objectFilterObj; }; /*** Uncomment these to check your work! ***/ const startingObj = {}; startingObj[6] = 3; startingObj[2] = 1; startingObj[12] = 4; const half = n => n / 2; console.log(objFilter(startingObj, half)); // should log: { 2: 1, 6: 3 } |
挑战13 rating
问题:
构建rating函数,接受参数为一个由函数组成的数组和一个值。数组中的函数的返回值皆为true或false。rating会返回一个表明将输入值运行于数组中的函数会返回true的百分比数。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Challenge 13 const rating = (arrOfFuncs, value) => { let trueCounter = 0; arrOfFuncs.forEach(el => { if(el(value)){ trueCounter++; } }) return trueCounter/arrOfFuncs.length * 100; }; /*** Uncomment these to check your work! ***/ const isEven = n => n % 2 === 0; const greaterThanFour = n => n > 4; const isSquare = n =>Math.sqrt(n) % 1 === 0; const hasSix = n => n.toString().includes('6'); const checks = [isEven, greaterThanFour, isSquare, hasSix]; console.log(rating(checks, 64)); // should log: 100 console.log(rating(checks, 66)); // should log: 75 |
挑战14 pipe
问题:
构建pipe函数,接受参数为一个由函数组成的数组和一个值。pipe会将输入值输入到数组的第一个函数中,然后再将得到的输出值输入到第二个函数中,然后输出值又再输入到第三个函数中,一直下去,直到得到数组的最后一个函数的输出值。pipe会返回这个最终输出值。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Challenge 14 const pipe = (arrOfFuncs, value) => { let output = value; arrOfFuncs.forEach(el => { output = el(output); }) return output; }; /*** Uncomment these to check your work! ***/ const capitalize = str => str.toUpperCase(); const addLowerCase = str => str + str.toLowerCase(); const repeat = str => str + str; const capAddlowRepeat = [capitalize, addLowerCase, repeat]; console.log(pipe(capAddlowRepeat, 'cat')); // should log: 'CATcatCATcat' |
挑战15 highestFunc
问题:
构建highestFunc函数,接受参数为一个对象(包含函数)和一个值。highestFunc会返回输入对象中运行输入值后得到最高值的函数所对应的键。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// Challenge 15 const highestFunc = (objOfFuncs, subject) => { let maxKey = ""; let maxNumber = Number.NEGATIVE_INFINITY; for(let key in objOfFuncs) { if(objOfFuncs[key](subject) > maxNumber){ maxNumber = objOfFuncs[key](subject); maxKey = key; } } return maxKey; }; /*** Uncomment these to check your work! ***/ const groupOfFuncs = {}; groupOfFuncs.double = n => n * 2; groupOfFuncs.addTen = n => n + 10; groupOfFuncs.inverse = n => n * -1; console.log(highestFunc(groupOfFuncs, 5)); // should log: 'addTen' console.log(highestFunc(groupOfFuncs, 11)); // should log: 'double' console.log(highestFunc(groupOfFuncs, -20)); // should log: 'inverse' |
闭包
挑战1 createFunction
问题:
构建createFunction函数,用于创建和返回函数。当被创建的函数被调用时,它会打印“hello”。
1 2 3 |
const function1 = createFunction(); // now we'll call the function we just created function1(); //should console.log('hello'); |
题解:
1 2 3 4 5 6 7 8 9 10 11 |
// Challenge 1 const createFunction = () => { const innerFunction = () => { console.log('hello'); } return innerFunction; }; // UNCOMMENT THESE TO TEST YOUR WORK! const function1 = createFunction(); function1(); |
挑战2 createFunctionPrinter
问题:
构建接受一个输入值作为参数的createFunctionPrinter函数,用于创建和返回一个特定函数。当特定函数被调用时,其应该打印特定函数被创建时输入createFunctionPrinter中的值。
1 2 3 4 5 |
const printSample = createFunctionPrinter('sample'); const printHello = createFunctionPrinter('hello') // now we'll call the functions we just created printSample(); //should console.log('sample'); printHello(); //should console.log('hello'); |
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Challenge 2 const createFunctionPrinter = (input) => { let inputValue = input; const innerFunction = (inputValue) => { console.log(input); } return innerFunction; }; // UNCOMMENT THESE TO TEST YOUR WORK! const printSample = createFunctionPrinter('sample'); printSample(); const printHello = createFunctionPrinter('hello'); printHello(); |
挑战3 outer
问题:
观察下面outer函数的实现代码。注意其会返回一个函数而且那个函数使用了不在其作用域的变量。尝试推断一下运行outer函数得到的输出值。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Challenge 3 const outer = () => { let counter = 0; // this variable is outside incrementCounter's scope const incrementCounter = () => { counter++; console.log('counter', counter); } return incrementCounter; }; const willCounter = outer(); const jasCounter = outer(); // Uncomment each of these lines one by one. // Before your do, guess what will be logged from each function call. willCounter(); willCounter(); willCounter(); jasCounter(); willCounter(); |
挑战4 addByX
问题:
构建addByX函数,其会返回一个接受一个输入值作为参数并与x相加的函数。
1 2 3 4 5 6 7 8 9 10 11 12 |
const addByTwo = addByX(2); addByTwo(1); //should return 3 addByTwo(2); //should return 4 addByTwo(3); //should return 5 const addByThree = addByX(3); addByThree(1); //should return 4 addByThree(2); //should return 5 const addByFour = addByX(4); addByFour(4); //should return 8 addByFour(10); //should return 14 |
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Challenge 4 const addByX = (x) => { const outerInput = x; const innerFunction = (innerInput) => { return x + innerInput; } return innerFunction; }; const addByTwo = addByX(2); // now call addByTwo with an input of 1 console.log(addByTwo(1)); // now call addByTwo with an input of 2 console.log(addByTwo(2)); |
挑战5 once
问题:
构建once函数,接受参数为一个回调函数并返回一个特定函数。当特定函数被第一次调用时,其会调用回调函数并返回输出值。如果其不是被第一次调用,则特定函数仅仅返回第一次调用时得到的回调函数返回值,而不是再次运行回调函数。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Challenge 5 const once = (func) => { let counter = 0; let onceResult = 0; const innerFunction = (el) => { counter++; if(counter === 1) { onceResult = func(el); return onceResult; } else{ return onceResult; } } return innerFunction; }; const onceFunc = once(addByTwo); // UNCOMMENT THESE TO TEST YOUR WORK! console.log(onceFunc(4)); //should log 6 console.log(onceFunc(10)); //should log 6 console.log(onceFunc(9001)); //should log 6 |
挑战6 after
问题:
构建after函数,接受一个数字n和一个回调函数作为参数。回调函数需要在通过after构建的函数运行第n次时才被运行。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Challenge 6 const after = (count, func) => { let counter = count; const innerFunction = (el) => { if(--counter === 0){ func(el); } } return innerFunction; }; const called = () =>console.log('hello'); const afterCalled = after(3, called); afterCalled(); // -> nothing is printed afterCalled(); // -> nothing is printed afterCalled(); // -> 'hello' is printed |
挑战7 delay
问题:
构建delay函数,作用为接受一个回调函数作为第一个参数,一个数值n(单位为毫秒)作为第二个参数,返回一个特定函数。delay构建的特定函数被调用后,须经n毫秒后才运行回调函数。任何其他赋给特定函数的参数会在n毫秒后被回调函数使用。提示:研究setTimeout();
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Challenge 7 const delay = (func, wait) => { const waitTime = wait; const innerFunction = (el) => { setTimeout((el) => { func(el); }, waitTime); } return innerFunction; }; const delayCalled = delay(called, 2000); delayCalled(); // "hello" after 2 seconds. |
挑战8 russianRoulette
问题:
构建russianRoulette函数,作用为接受一个数值参数(假设为n)并返回一个特定函数。此特定函数不接受输入参数,而且会在前n-1次调用时返回字符串“click“,在第n次调用时则返回字符串”bang“,n次以后再调用皆返回字符串”reload to play again”。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
// Challenge 8 const russianRoulette = (num) => { let counter = num; const innerFunction = () => { counter--; if(counter>0) { return"click"; } elseif(counter==0){ return"bang"; } else{ return"reload to play again"; } } return innerFunction; }; /*** Uncomment these to check your work! ***/ const play = russianRoulette(3); console.log(play()); // should log: 'click' console.log(play()); // should log: 'click' console.log(play()); // should log: 'bang' console.log(play()); // should log: 'reload to play again' console.log(play()); // should log: 'reload to play again' // Challenge 8 const russianRoulette = (num) => { let counter = num; const innerFunction = () => { counter--; if(counter>0) { return"click"; } elseif(counter==0){ return"bang"; } else{ return"reload to play again"; } } return innerFunction; }; /*** Uncomment these to check your work! ***/ const play = russianRoulette(3); console.log(play()); // should log: 'click' console.log(play()); // should log: 'click' console.log(play()); // should log: 'bang' console.log(play()); // should log: 'reload to play again' console.log(play()); // should log: 'reload to play again' |
挑战9 average
问题:
构建average函数,不接受参数,并返回一个特定函数(接受一个数值作为参数或无参数)。当average创建的特定函数被输入数值参数的方式调用时,返回值为所有曾经被输入到特定函数的数值参数的平均值(重复数值视为分别的数值)。当特定函数被无参数的方式调用时,返回当前的平均值。如果特定函数在无参数方式调用时不曾被输入数值参数的方式调用过,则返回0。
题解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Challenge 9 const average = () => { let averageValue = 0; let argumentCounter = 0; let argumentSum = 0; const innerFunction = (el) => { if(el == undefined) { return averageValue; } else{ argumentCounter++; argumentSum += el; averageValue = argumentSum / argumentCounter; return averageValue; } } return innerFunction; }; /*** Uncomment these to check your work! ***/ const avgSoFar = average(); console.log(avgSoFar()); // should log: 0 console.log(avgSoFar(4)); // should log: 4 console.log(avgSoFar(8)); // should log: 6 console.log(avgSoFar()); // should log: 6 console.log(avgSoFar(12)); // should log: 8 console.log(avgSoFar()); // should log: 8 |
挑战10 makeFuncTester
问题:
构建makeFuncTester函数,接受参数为一个二维数组(其中第二维数组仅含两个元素),返回一个接收回调函数作为参数的特定函数。当二维数组的每一个子数组的第一个元素输入到回调函数时都产生与第二个元素相同的返回值时,特定函数返回ture,