前端面试常见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; returnfunction 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(){ letargs= [...arguments]; let adder = function(){ args.push(...arguments); return adder; } adder.toString = function (){ return args.reduce((a,b)=>a+b) } return adder; }

【前端面试常见js手写题记录(含答案)】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{ 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); }); } };

    推荐阅读