前端面试手写代码合集

177 阅读2分钟

函数防抖

  • debounce

    • search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
    • window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
 // 防抖(一段时间会等,然后带着一起做了)
 function debounce(fn, delay){
     let timerId = null
     return function(){
        // 取debounce执行作用域的this
         const context = this
         if(timerId){window.clearTimeout(timerId)}
         timerId = setTimeout(()=>{
             fn.apply(context, arguments)
             timerId = null
         },delay)
     }
 }
 const debounced = debounce(()=>console.log('hi'))
 debounced()

函数节流

  • throttle

    • 鼠标不断点击触发,mousedown(单位时间内只触发一次)
    • 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
// 节流(一段时间执行一次之后,就不执行第二次)
 function throttle(fn, delay){
     let canUse = true
     return function(){
         if(canUse){
             fn.apply(this, arguments)
             canUse = false
             setTimeout(()=>canUse = true, delay)
         }
     }
 }

 const throttled = throttle(()=>console.log('hi'))
 throttled()

数组扁平化

const flat = (arr) => {
  let arrResult = []
  for(let i=0, len=arr.length; i<len; i++){
    if(Array.isArray(arr[i])){
      arrResult.push(...flat(arr[i]))
      // arrResult = arrResult.concat(flat(arr[i]))
    }else{
      arrResult.push(arr[i])
    }
  }
  return arrResult;
}
flat(arr)

柯里化

function createCurry(func, args) {
    var argity = func.length;
    var args = args || [];

    return function () {
        var _args = [].slice.apply(arguments);
        args.push(..._args);

        if (args.length < argity) {
            return createCurry.call(this, func, args);
        }

        return func.apply(this, args);
    }
}

斐波那契数列

let fib = function(n) {
    let i = 2
    let res = [0,1,1]
    while(i <= n) {
        res[i] = res[i - 1] + res[i - 2]
        i++
    }
    return res[n]
}

得到一个两数之间的随机整数

这个例子返回了一个在指定值之间的随机整数。这个值不小于 min (如果 min 不是整数,则不小于 min 的向上取整数),且小于(不等于)max

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
}

路径总和

var pathSum = function (root, sum) {
  if (root === null) return 0
  return pathByDFS(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum)
}

var pathByDFS = function (root, sum) {
  if (root === null) return 0
  var res = 0
  if (root.val === sum) {
    res++
  }
  res += pathByDFS(root.left, sum - root.val)
  res += pathByDFS(root.right, sum - root.val)
  return res
}

function TreeNode(val) {
  this.val = val
  this.left = this.right = null
}

AJAX

 var request = new XMLHttpRequest()
 request.open('GET', '/a/b/c?name=ff', true);
 request.onreadystatechange = function () {
   if(request.readyState === 4 && request.status === 200) {
     console.log(request.responseText);
   }};
 request.send();

Promise

function Promise(executor) {
    let self = this;
    self.status = 'pending'; //等待态
    self.value = undefined;  //成功的返回值
    self.reason = undefined; //失败的原因

    function resolve(value){
        if(self.status === 'pending'){
            self.status = 'resolved';
            self.value = value;
        }
    }
    function reject(reason) {
        if(self.status === 'pending') {
            self.status = 'rejected';
            self.reason = reason;
        }
    }
    try{
        executor(resolve, reject);
    }catch(e){
        reject(e);// 捕获时发生异常,就直接失败
    }
}
//onFufiled 成功的回调
//onRejected 失败的回调
Promise.prototype.then = function (onFufiled, onRejected) {
    let self = this;
    if(self.status === 'resolved'){
        onFufiled(self.value);
    }
    if(self.status === 'rejected'){
        onRejected(self.reason);
    }
}
module.exports = Promise;

粗暴深拷贝

function deepCopy(obj1){ 
    let _obj = JSON.stringify(obj1); 
    let obj2 = JSON.parse(_obj); 
    return obj2; 
} 
var a = [1, [1, 2], 3, 4]; 
var b = deepCopy(a);

async await

async function f() {
    try {
        await new Promise(function (resolve, reject) { 
            throw new Error('出错了'); 
        }); 
    } 
    catch(e) { } 
    return await('hello world'); 
}

new 操作符

function myNew(){
    const obj = new Object();
    Constructor = Array.prototype.shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    let ret = Constructor.apply(obj,arguments); // 判断构造函数是否存在返回值
    return typeof ret === 'object'? ret : obj;
}