前端面试常见js手写题记录(含答案)

本篇文章主要记录了前端笔试中常考的基础手写题,对源码进行了一点缩减,也是为了能在笔试中能更快的写出来。

防抖节流:

//防抖
function debounce(fn, time) {
  let timer;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.call(this, ...arguments);
    }, time);
  };
}

//节流
function throttle(fn, delay) {
  var prev = Date.now();
  return function () {
    var now = Date.now();
    if (now - prev >= delay) {
      fn.call(this, ...arguments);
      prev = Date.now();
    }
  };
}

继承:

//组合继承
function Parent(name){
    this.name = name;
}
Parent.prototype.getName = function(){
    console.log(this.name)
}
function Child(name){
Parent.call(this,name);
}
Child.prototype = new Parent();



//寄生组合
function Parent(name){
    this.name = name;
}
Parent.prototype.getName = function () { console.log(this.name) }
function Child(name){
    Parent.call(this,name);
}
Child.prototype = Object.create(Parent.prototype,{
    constructor:{
        value:Child,
        writable:true,
        enumerable:false,
        configurable:true
    }
})

call、apply、bind实现:


//call
Function.prototype.myCall = function (content, ...args) {
  content = content || window;
  content.fn = this;
  let result = content.fn(...args);
  delete content.fn;
  return result;
};

//apply
Function.prototype.myApply = function (content, arr) {
  content = content || window;
  content.fn = this;
  let result = arr && content.fn(...arr);
  delete content.fn;
  return result;
};


//bind
Function.prototype.myBind = function (content, ...args) {
  const that = this;
  return  function F() {
    if (this instanceof F) {
      return new that(...args, ...arguments); // 因为返回了一个函数,我们可以 new F(),所以需要判断
    }
    return that.apply(content, [...args, ...arguments]);
  };
};

柯里化:

//定长柯里化
function curry(fn, ...presetArgs) {
  return function (...args) {
    let allargs = [...presetArgs, ...args];
    if (allargs.length >= fn.length) {
      fn.apply(this, allargs);
    } else {
      return curry(fn, ...allargs);
    }
  };
}


//累加函数
function add(){
    let  args= [...arguments];
    let adder = function(){
        args.push(...arguments);
        return adder;
    }
    adder.toString = function (){
        return args.reduce((a,b)=>a+b)
    }
    return adder;
}

new、instanceof、object.create实现:


//new
function myNew(Con, ...args) {
  let obj = {};
  obj.__proto__ = Con.prototype;
  let result = Con.call(obj, ...args);
  return result instanceof Object ? result : obj;
}



//instanceof
function myInstanceof(left, right) {
  let prototype = right.prototype;
  left = left.__proto__;
  while (true) {
    if (left === null || left === undefined) return false;
    if (prototype === left) return true;
    left = left.__proto__;
  }
}

//object.create
function myCreate(p) {
    function F(){}
    F.prototype = p;
    return new F();
}

其他:

//数组map
function map(arr,callback) { 
    if(Array.isArray(arr)){
        let newArr = [];
        for(let i = 0 ;i<arr.length;i++){
            newArr[i] = callback(arr[i],i,arr);
        }
        return newArr;
    }
    return [];
 }

//深拷贝
const deepCopy = function (obj) {
  let newObj = obj instanceof Array ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] =
        typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key];
    }
  }
  return newObj;
};

//冒泡排序
const popSort = (arr)=>{
  for(let i=0;i<=arr.length-1;i++){
      for(let j=i+1;j<=arr.length;j++){
             if (arr[i] > arr[j]) {
               [arr[i], arr[j]] = [arr[j], arr[i]];
             }
      }
 
  }
}

50行简单版Promise实现:


//当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行
const PENDING = "pending",
  RESOLVED = "fulfilled",
  REJECTED = "rejected";
function myPromise(fn) {
  this.val = null;
  this.state = PENDING;
  this.resolvedCallback = [];
  this.rejectedCallback = [];
  try {
    fn(resolve.bind(this), reject.bind(this));
  } catch (e) {
    this.reject(e);
  }
  function resolve(val) {
    if (this.state === PENDING) {
      setTimeout(() => {
        this.state = RESOLVED;
        this.val = val;
        this.resolvedCallback.forEach((cb) => cb(val));
      });
    }
  }
  function reject(val) {
    if (this.state === PENDING) {
      setTimeout(() => {
        this.state = REJECTED;
        this.val = val;
        this.rejectedCallback.forEach((cb) => cb(val));
      });
    }
  }
}
myPromise.prototype.then = function (onResolve, onReject) {
  onResolve = typeof onResolve === "function" ? onResolve : (v) => v;
  onReject =
    typeof onReject === "function"
      ? onResolve
      : (r) => {
          throw r;
        };
  if (this.state === PENDING) {
    this.resolvedCallback.push(onResolve);
    this.rejectedCallback.push(onReject);
  }
  if (this.state === RESOLVED) {
    setTimeout(() => {
      onResolve(this.val);
    });
  }
  if (this.state === REJECTED) {
    setTimeout(() => {
      onReject(this.val);
    });
  }
};
版权声明:程序员胖胖胖虎阿 发表于 2023年9月3日 上午8:32。
转载请注明:前端面试常见js手写题记录(含答案) | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...