JavaScript:算法练习

来源博客:【Harryの心阁

第十六天


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

Javascript题目1

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

问题解答1

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

解题思路1

setTimeout方法+递归

let timer;

function countFn(start, end) {
  clearTimeout(timer) // 调用函数之前执行一次清除定时器,以免影响下一次 定时操作
  console.log(start++);
  timer = setTimeout(() => {
    if (start <= end) {
      return countFn(start, end)
    }
    return {
      clear() {
        clearTimeout(timer)
      }
    }
  }, 100)
}
countFn(4, 9)

setInterval方法

let timer;

function countFn(start, end) {
  //立即输出第一个值
  console.log(start++);
  timer = setInterval(
    function() {
      if (start <= end) {
        console.log(start++);
      } else {
        clearInterval(timer);
      }
    }, 100);
  //返回一个对象
  return {
    cancel() {
      clearInterval(timer);
    }
  };
}
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

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

Javascript题目3

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

问题解答3

解题思路3

 // function argsAsArray(fn, arr) {
 //   return fn(arr[0], arr[1], arr[2]);
 // }
 // 用apply

 // function argsAsArray(fn, arr) {
 //   return fn.apply(fn, arr);
 //   return fn.apply(this, arr);
 // }

 // 用call
 function argsAsArray(fn, arr) {
   return fn.call(this, arr[0], arr[1], arr[2]);
   //return fn.call(fn, arr[0], arr[1], arr[2]);
 }
 //  使用扩展运算符的方法
 function argsAsArray(fn, arr) {
   return fn(...arr);
 }
 console.log(argsAsArray(function(params, name, punc) {
   return `${params},${name + punc}`
 }, ['hello', 'world', '!']));

Javascript题目4

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

问题解答4

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

partial(sayIt, 'Hello', 'Ellie')('!!!');
  • 输出
Hello, Ellie!!!

解题思路4

bind方法

// 第一种方法
function partial(fn, str1, str2) {
  // return result=(str3)=>fn.bind(this, str1, str2)(str3); // bind fn.bind(this, str1, str2)
  // return result = (str3) => fn.apply(this, [str1, str2, str3]); //apply
  return result = (str3) => fn.call(this, str1, str2, str3); // call
}

// 第二种方法
let partal = (fn, str1, st2) => result = (str3) => fn(str1, str2, str3)

Javascript题目5

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

问题解答5

解题思路5

// function userArguments(...arg) {
//   return [...arg].reduce((init, pre) => init + pre)
// }
function userArguments() {
  // 第一种
  // let arr = Array.prototype.slice.call(arguments)
  // 第二种
  // let arr = [].slice.call(arguments)
  // 第三种
  // let arr = Array.from(arguments)
  // 第四种
  // let arr = [...arguments]
  // return eval(arr.join("+"))
  // 第五种 在传入的参数不重复的情况下使用
  // let result = 0;
  // for (let i of new Set(arguments).values()) {
  //   result += i
  // }
  // return result
  // 第六种
  return Array.prototype.reduce.call(arguments, (a, b) => a + b)
}
console.log(userArguments(1, 2, 3, 2, 1));

Javascript题目6

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

问题解答6

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

解题思路6

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

Javascript题目7

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

问题解答7

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

解题思路7

function partialUsingArguments(fn) {
  //先获取p函数第一个参数之后的全部参数
  var args = [].slice.call(arguments, 1);
  //声明result函数
  return result = function() {
    //使用concat合并两个或多个数组中的元素
    return fn.apply(this, args.concat([].slice.call(arguments)));
  };
}

function fn() {
  return [...arguments].reduce((a, b) => a + b)
}
console.log(partialUsingArguments(fn, 2, 3, 2)()); //7
console.log(fn(2, 3, 2)); //7

Javascript题目

题目

问题解答

// 第一种方法 本方法
// function currylt(fn) {
//   console.log(fn.length);
//   return a = (str1) => {
//     return b = (str2) => {
//       return c = (str3) => {
//         return fn.apply(null, [str1, str2, str3])
//       }
//     }
//   }
// }
// 第二种柯里化方法
let args = [];

function currylt(fn) {
  let a = (arg) => {
    args.push(arg)
    if (args.length < fn.length) {
      return a
    } else {
      return fn.apply(null, args)
    }
  }
  return a
}
var fn = function(a, b, c) {
  return a + b + c;
}
console.log(currylt(fn)(1)(2)(3));
console.log(fn(1, 2, 3));

解题思路

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

知识扩展

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

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

公众号:今日在学

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Harry-iu

顺手给小编加个鸡腿????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值