第十六天


(题目来源: 前端每日知识3+1)

Javascript题目1

题目 : 实现一个打点计时器(js)

问题解答1

  1. 从start到end (包含start和end), 每隔100毫秒console.log 一个数字,每次数字增幅为1
  2. 返回的对象中需要包含一个 cancel方法,用于停止定时操作
  3. 第一个数需要立即输出

解题思路1

setTimeout方法+递归

  1. let timer;
  2. function countFn(start, end) {
  3. clearTimeout(timer) // 调用函数之前执行一次清除定时器,以免影响下一次 定时操作
  4. console.log(start++);
  5. timer = setTimeout(() => {
  6. if (start <= end) {
  7. return countFn(start, end)
  8. }
  9. return {
  10. clear() {
  11. clearTimeout(timer)
  12. }
  13. }
  14. }, 100)
  15. }
  16. countFn(4, 9)

setInterval方法

  1. let timer;
  2. function countFn(start, end) {
  3. //立即输出第一个值
  4. console.log(start++);
  5. timer = setInterval(
  6. function() {
  7. if (start <= end) {
  8. console.log(start++);
  9. } else {
  10. clearInterval(timer);
  11. }
  12. }, 100);
  13. //返回一个对象
  14. return {
  15. cancel() {
  16. clearInterval(timer);
  17. }
  18. };
  19. }
  20. countFn(4, 9)

Javascript题目2

题目 : 实现fizzBuzz函数, 参数num与返回值的关系如下(js)

问题解答2

  1. 如果num能同时被3和5整除, 返回字符串fizzbuzz
  2. 如果num能被3整除, 返回字符串fzz
  3. 如果num能被5整除, 返回字符串buzz
  4. 如果参数为空或者不是Number类型, 返回false
  5. 其余情况, 返回参数num

解题思路2

  1. function fizzBuzz(num) {
  2. if (isNaN(num) || typeof num !== Number || num.length == 0) return false;
  3. // Object.prototype.toString.call(num).match(/(?<=\[object\s)(\w*)(?=\])/g)[0]
  4. if (num % 3 == 0 && num % 5 == 0) {
  5. return 'fizzbuzz'
  6. } else if (num % 3 == 0) {
  7. return 'fizz'
  8. } else if (num % 5 == 0) {
  9. return 'buzz'
  10. } else {
  11. return num
  12. }
  13. }
  14. console.log(fizzBuzz('2'));

Javascript题目3

题目 : 将数组arr中的元素作为调用函数fn的参数(js)

问题解答3

解题思路3

  1. // function argsAsArray(fn, arr) {
  2. // return fn(arr[0], arr[1], arr[2]);
  3. // }
  4. // 用apply
  5. // function argsAsArray(fn, arr) {
  6. // return fn.apply(fn, arr);
  7. // return fn.apply(this, arr);
  8. // }
  9. // 用call
  10. function argsAsArray(fn, arr) {
  11. return fn.call(this, arr[0], arr[1], arr[2]);
  12. //return fn.call(fn, arr[0], arr[1], arr[2]);
  13. }
  14. // 使用扩展运算符的方法
  15. function argsAsArray(fn, arr) {
  16. return fn(...arr);
  17. }
  18. console.log(argsAsArray(function(params, name, punc) {
  19. return `${params},${name + punc}`
  20. }, ['hello', 'world', '!']));

Javascript题目4

题目 : 已知函数fn执行需要三个参数, 请实现函数partial, 调用之后满足以下条件(js)

问题解答4

  1. 返回一个函数result,该函数接收一个参数
  2. 执行result(str3),返回的结果与fn(str1, str2, str3)一致
  • 输入
  1. var sayIt = function(greeting, name, punctuation) {
  2. return greeting + ',' + name + (punctuation || '!');
  3. };
  4. partial(sayIt, 'Hello', 'Ellie')('!!!');
  • 输出
  1. Hello, Ellie!!!

解题思路4

bind方法

  1. // 第一种方法
  2. function partial(fn, str1, str2) {
  3. // return result=(str3)=>fn.bind(this, str1, str2)(str3); // bind fn.bind(this, str1, str2)
  4. // return result = (str3) => fn.apply(this, [str1, str2, str3]); //apply
  5. return result = (str3) => fn.call(this, str1, str2, str3); // call
  6. }
  7. // 第二种方法
  8. let partal = (fn, str1, st2) => result = (str3) => fn(str1, str2, str3)

Javascript题目5

题目 : 函数useArguments可以接收1个及以上的参数. 请实现函数useArguments, 返回所有调用参数相加后的结果. 本题的测试参数全部为Number类型, 不需考虑参数转换.(js)

问题解答5

解题思路5

  1. // function userArguments(...arg) {
  2. // return [...arg].reduce((init, pre) => init + pre)
  3. // }
  4. function userArguments() {
  5. // 第一种
  6. // let arr = Array.prototype.slice.call(arguments)
  7. // 第二种
  8. // let arr = [].slice.call(arguments)
  9. // 第三种
  10. // let arr = Array.from(arguments)
  11. // 第四种
  12. // let arr = [...arguments]
  13. // return eval(arr.join("+"))
  14. // 第五种 在传入的参数不重复的情况下使用
  15. // let result = 0;
  16. // for (let i of new Set(arguments).values()) {
  17. // result += i
  18. // }
  19. // return result
  20. // 第六种
  21. return Array.prototype.reduce.call(arguments, (a, b) => a + b)
  22. }
  23. console.log(userArguments(1, 2, 3, 2, 1));

Javascript题目6

题目 : 实现函数 callIt, 调用之后满足如下条件(js)

问题解答6

  • 返回的结果为调用 fn 之后的结果
  • fn 的调用参数为 callIt 的第一个参数之后的全部参数

解题思路6

  1. // 解构方法
  2. function calllt(fn) {
  3. let [f, ...arg] = arguments
  4. return f.apply(this, arg)
  5. }
  6. // slice
  7. // function calllt(fn) {
  8. // return fn.apply(this, Array.prototype.slice.call(arguments, 1))
  9. // }
  10. console.log(calllt(function() {
  11. return [...arguments].reduce((a, b) => a + b)
  12. }, 2, 1, 3, 2)); //8

Javascript题目7

题目 : 实现函数 partialUsingArguments, 调用之后满足如下条件(js)

问题解答7

  1. 返回一个函数 result
  2. 调用 result 之后,返回的结果与调用函数 fn 的结果一致
  3. fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数

解题思路7

  1. function partialUsingArguments(fn) {
  2. //先获取p函数第一个参数之后的全部参数
  3. var args = [].slice.call(arguments, 1);
  4. //声明result函数
  5. return result = function() {
  6. //使用concat合并两个或多个数组中的元素
  7. return fn.apply(this, args.concat([].slice.call(arguments)));
  8. };
  9. }
  10. function fn() {
  11. return [...arguments].reduce((a, b) => a + b)
  12. }
  13. console.log(partialUsingArguments(fn, 2, 3, 2)()); //7
  14. console.log(fn(2, 3, 2)); //7

Javascript题目

题目 : 实现一个打点计时器(js) - 图1

问题解答

  1. // 第一种方法 本方法
  2. // function currylt(fn) {
  3. // console.log(fn.length);
  4. // return a = (str1) => {
  5. // return b = (str2) => {
  6. // return c = (str3) => {
  7. // return fn.apply(null, [str1, str2, str3])
  8. // }
  9. // }
  10. // }
  11. // }
  12. // 第二种柯里化方法
  13. let args = [];
  14. function currylt(fn) {
  15. let a = (arg) => {
  16. args.push(arg)
  17. if (args.length < fn.length) {
  18. return a
  19. } else {
  20. return fn.apply(null, args)
  21. }
  22. }
  23. return a
  24. }
  25. var fn = function(a, b, c) {
  26. return a + b + c;
  27. }
  28. console.log(currylt(fn)(1)(2)(3));
  29. console.log(fn(1, 2, 3));

解题思路

  • 柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数, 并且返回接受余下的参数且返回结果的新函数的技术.

知识扩展

  • apply和call方法都是改变this的指向, apply接受两个参数一个是函数运行的作用域(this), 还有一个就是数组; call接受一个或者多个参数, 与apply不同的是, 传递给函数的参数必须列举出来
  • bind与以上方法类似, 使用bind函数会创建一个新的函数, 可以改变参数的结构, bind不是立即执行, 未传入参数时, 并未执行, 只是返回一个函数, 等待参数传入
  • 将arguments类数组转换成正常的数组的方法
  1. 第一种使用`Array.prototype.slice.call(arguments)`
  2. 将函数传入的具有length对象转换成数组的形式
  3. 第二种是`[].slice.call(arguments)`
  4. 与上面的方法等价
  5. 第三种使用es6语法`Array.from()`
  6. 方法可以将类数组转换成正常的数组
  7. 第四种`new Set()`
  8. 可遍历, 去重
  9. 第五种使用`...`
  10. 扩展运算符

JS中的call和apply用法总结
手写bind函数
手写bind函数2